diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/kernel/acpi/acpi.c | 3 | ||||
-rw-r--r-- | src/kernel/kernel.c | 9 | ||||
-rw-r--r-- | src/kernel/smbios/smbios.c | 66 | ||||
-rw-r--r-- | src/kernel/smbios/smbios.h | 32 |
4 files changed, 105 insertions, 5 deletions
diff --git a/src/kernel/acpi/acpi.c b/src/kernel/acpi/acpi.c index e0d260b..1cf5ca6 100644 --- a/src/kernel/acpi/acpi.c +++ b/src/kernel/acpi/acpi.c @@ -155,6 +155,7 @@ int acpi_install() { SCI_EN = 1; vga_log("Installed ACPI", 5); + acpi_enable(); return 0; } // Else: \_S5 parse error @@ -168,8 +169,6 @@ int acpi_install() { } void acpi_poweroff() { - acpi_enable(); - if (SCI_EN == 0) { serial_write("ACPI shutdown is not supported\n"); return; diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index b133a0c..9be7914 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -9,6 +9,7 @@ #include <kernel/mutliboot.h> #include <kernel/fs/initrd.h> #include <kernel/syscall/syscall.h> +#include <kernel/smbios/smbios.h> extern void switch_to_user(); @@ -23,12 +24,14 @@ void kernel_main(struct multiboot *mboot_ptr) { idt_install(); isrs_install(); irq_install(); - set_optimal_resolution(); // Install drivers - asm volatile ("cli"); - keyboard_install(); asm volatile ("sti"); + set_optimal_resolution(); + keyboard_install(); + + // Get hardware information + get_smbios(); // Setup initial ramdisk assert(mboot_ptr->mods_count > 0); diff --git a/src/kernel/smbios/smbios.c b/src/kernel/smbios/smbios.c new file mode 100644 index 0000000..0275f48 --- /dev/null +++ b/src/kernel/smbios/smbios.c @@ -0,0 +1,66 @@ +#include <stdint.h> +#include <kernel/graphics/vesa.h> +#include <stddef.h> +#include <kernel/io/io.h> +#include <kernel/smbios/smbios.h> + +struct smbios_entry { + int8_t signature[4]; + uint8_t checksum; + uint8_t length; + uint8_t major_version; + uint8_t minor_version; + uint8_t max_structure_size; + int8_t entry_point_revision; + int8_t formatted_area[5]; + int8_t entry_point_signature[5]; + uint8_t checksum2; + uint16_t table_length; + uint32_t table_address; + uint16_t number_of_structures; + uint8_t bcd_revision; +}; + +struct smbios_entry *smbios = 0; + +size_t smbios_table_len(struct smbios_header *header) { + size_t i; + const char *strtab = (char *) header + header->length; + for (i = 1; strtab[i - 1] != '\0' || strtab[i] != '\0'; i++); + return header->length + i + 1; +} + +struct smbios_entry *get_smbios() { + if (smbios != 0) return smbios; + + char *mem = (char *) 0xF0000; + int length, i; + unsigned char checksum; + while ((unsigned int) mem < 0x100000) { + if (mem[0] == '_' && mem[1] == 'S' && mem[2] == 'M' && mem[3] == '_') { + length = mem[5]; + checksum = 0; + for (i = 0; i < length; i++) { + checksum += mem[i]; + } + if (checksum == 0) break; + } + mem += 16; + } + + if ((unsigned int) mem == 0x100000) { + warn("No SMBIOS found!"); + return 0; + } + + smbios = (struct smbios_entry *) mem; + if (smbios->major_version != 2) warn("Non-supported SMBIOS version"); + smbios_table((struct smbios_header *) mem); + return smbios; +} + +void smbios_table(struct smbios_header *header) { + serial_write("\n\n"); + struct smbios_0 *table = (struct smbios_0 *) (header + sizeof(struct smbios_header)); + serial_write(table->bios_version); +} diff --git a/src/kernel/smbios/smbios.h b/src/kernel/smbios/smbios.h new file mode 100644 index 0000000..384119c --- /dev/null +++ b/src/kernel/smbios/smbios.h @@ -0,0 +1,32 @@ +#ifndef MELVIX_SMBIOS_H +#define MELVIX_SMBIOS_H + +struct smbios_header { + uint8_t type; + uint8_t length; + uint16_t handle; +}; + +struct smbios_0 { + char *vendor; + char *bios_version; + uint16_t bios_start; + char *bios_release_data; + uint8_t bios_size; + uint64_t bios_characteristics; +}; + +struct smbios_1 { + char *manufacturer; + char *product_name; + char *version; + char *serial_number; + uint8_t uuid[16]; + uint8_t wakeup_type; +}; + +struct smbios_entry *get_smbios(); + +void smbios_table(struct smbios_header *header); + +#endif |