aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/kernel/acpi/acpi.c3
-rw-r--r--src/kernel/kernel.c9
-rw-r--r--src/kernel/smbios/smbios.c66
-rw-r--r--src/kernel/smbios/smbios.h32
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