aboutsummaryrefslogtreecommitdiff
path: root/src/kernel/smbios
diff options
context:
space:
mode:
authorMarvin Borner2019-11-03 21:37:31 +0100
committerMarvin Borner2019-11-03 21:37:31 +0100
commit2180357ff5edbd4c85e125ea5c45d9b2a2026944 (patch)
tree4de62d243617c54afc0d0bfdc56caa668a22c0fb /src/kernel/smbios
parent39b20774fc4684f390aa426148371c316e37c98d (diff)
Began system management bios implementation and fixed things
Diffstat (limited to 'src/kernel/smbios')
-rw-r--r--src/kernel/smbios/smbios.c66
-rw-r--r--src/kernel/smbios/smbios.h32
2 files changed, 98 insertions, 0 deletions
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