summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/amd64/acpi.c7
-rw-r--r--src/arch/amd64/boot.S4
-rw-r--r--src/arch/amd64/linker.ld38
-rw-r--r--src/arch/amd64/mboot.c138
-rw-r--r--src/arch/amd64/mboot.h2
-rw-r--r--src/arch/amd64/serial.c4
-rw-r--r--src/arch/amd64/shim.c5
7 files changed, 125 insertions, 73 deletions
diff --git a/src/arch/amd64/acpi.c b/src/arch/amd64/acpi.c
index 83f2014..70c2f38 100644
--- a/src/arch/amd64/acpi.c
+++ b/src/arch/amd64/acpi.c
@@ -31,7 +31,7 @@ struct rsdp {
char oemid[6];
uint8_t revision;
uint32_t rsdt_addr;
-} __attribute__((packed));
+};
// eXtended system descriptor pointer
// ACPI 2.0
@@ -46,7 +46,7 @@ struct xsdp {
uint64_t xsdt_addr;
uint8_t extendeid_checksum;
uint8_t reserved[3];
-} __attribute__((packed));
+};
// root system descriptor table
// ACPI 1.0
@@ -161,10 +161,8 @@ static bool checksum(uint8_t *data, size_t len) {
}
static int read_s5_addr(struct acpi_state *state) {
- serial_out_str("a");
uintptr_t ptr = state->fadt.dsdt;
char *s5_addr = (void*) (ptr + 36);
- serial_out_str("a");
int dsdt_len = *((int*) (ptr+1)) - 36;
while (0 < dsdt_len--) {
@@ -256,6 +254,7 @@ int acpi_init_rsdt(struct rsdt *rsdt) {
int acpi_init_xsdt(struct xsdt *xsdt) {
xsdt = mmap(xsdt, sizeof(struct xsdt));
+ return -1;
state.dst.xsdt = xsdt;
state.version = 2;
diff --git a/src/arch/amd64/boot.S b/src/arch/amd64/boot.S
index 55d942b..455b68b 100644
--- a/src/arch/amd64/boot.S
+++ b/src/arch/amd64/boot.S
@@ -90,6 +90,8 @@ start:
push DWORD 0
push ebx
+ push DWORD 0
+ push eax
mov edi, 0x1000
mov cr3, edi
@@ -143,8 +145,10 @@ code64:
xor rbp, rbp ; set ebp to 0 so we know where to end stack traces
pop rdi
+ pop rsi
call amd64_shim
mov rdi, rax
+ xor rsi, rsi
sti
call kmain
diff --git a/src/arch/amd64/linker.ld b/src/arch/amd64/linker.ld
new file mode 100644
index 0000000..0032765
--- /dev/null
+++ b/src/arch/amd64/linker.ld
@@ -0,0 +1,38 @@
+ENTRY(start)
+
+SECTIONS {
+ . = 1M;
+
+ kernel_start = .;
+
+ .boot BLOCK(4K) : ALIGN(4K)
+ {
+ *(.multiboot)
+ }
+
+ .rodata BLOCK(4K) : ALIGN(4K)
+ {
+ *(.rodata)
+ }
+
+ .data BLOCK(4K) : ALIGN(4K)
+ {
+ *(.data)
+ }
+
+ text_start = .;
+
+ .text BLOCK(4K) : ALIGN(4K)
+ {
+ *(.text)
+ }
+
+ text_end = .;
+
+ .bss BLOCK(4K) : ALIGN(4K)
+ {
+ *(.bss)
+ }
+
+ kernel_end = .;
+}
diff --git a/src/arch/amd64/mboot.c b/src/arch/amd64/mboot.c
index 6c3c413..b7124df 100644
--- a/src/arch/amd64/mboot.c
+++ b/src/arch/amd64/mboot.c
@@ -1,17 +1,25 @@
-#include "mboot.h"
-#include "serial.h"
-#include "shim.h"
-
+#include <shim.h>
#include <lib.h>
#include <stdint.h>
+#include <panic.h>
+
+#include "mboot.h"
+
+#define MBOOT_HEADER_MAGIC 0x36D76289
+
+#define MBOOT_CMDLINE 1
+#define MBOOT_MEMORY_MAP 6
+#define MBOOT_ELF_SYMBOLS 9
+#define MBOOT_OLD_RSDP 14
+#define MBOOT_NEW_RSDP 15
extern char symtab;
#define kaddr(addr) ((uintptr_t)(&addr))
-typedef unsigned char mboot_uint8_t;
-typedef unsigned short mboot_uint16_t;
-typedef unsigned int mboot_uint32_t;
-typedef unsigned long long mboot_uint64_t;
+typedef uint8_t mboot_uint8_t;
+typedef uint16_t mboot_uint16_t;
+typedef uint32_t mboot_uint32_t;
+typedef uint64_t mboot_uint64_t;
struct mboot_info {
mboot_uint32_t total_size;
@@ -25,24 +33,17 @@ struct mboot_tag {
char data[];
};
-enum mboot_tag_type {
- MBOOT_CMDLINE = 0,
- MBOOT_MEMORYMAP = 6,
- MBOOT_SYMBOLS = 9,
- MBOOT_RSDP = 14,
- MBOOT_XSDP = 15,
-};
-
-struct mboot_elf_header_layout {
+struct mboot_tag_elf_sections {
mboot_uint32_t type;
mboot_uint32_t size;
- mboot_uint32_t num;
- mboot_uint32_t entsize;
- mboot_uint32_t shndx;
- char elf_section_headers[];
+ mboot_uint16_t num;
+ mboot_uint16_t entsize;
+ mboot_uint16_t shndx;
+ mboot_uint16_t reserved;
+ char sections[];
};
-struct mboot_elf_section_header {
+struct mboot_tag_elf_sections_entry {
mboot_uint32_t sh_name;
mboot_uint32_t sh_type;
mboot_uint64_t sh_flags;
@@ -55,45 +56,46 @@ struct mboot_elf_section_header {
mboot_uint64_t sh_entsize;
};
-struct mboot_memory_segment {
+struct mboot_mmap_entry {
mboot_uint64_t addr;
mboot_uint64_t len;
mboot_uint32_t type;
- mboot_uint32_t reserved;
+ mboot_uint32_t zero;
};
-struct mboot_memory_map {
- mboot_uint32_t tag;
+struct mboot_tag_mmap {
+ mboot_uint32_t type;
mboot_uint32_t size;
mboot_uint32_t entry_size;
mboot_uint32_t entry_version;
- struct memory_segment entries[];
+ struct mboot_mmap_entry entries[];
};
-struct mboot_rsdp {
- mboot_uint32_t tag;
+
+struct mboot_tag_old_rsdp {
+ mboot_uint32_t type;
mboot_uint32_t size;
mboot_uint8_t rsdp[];
};
-struct mboot_xsdp {
- mboot_uint32_t tag;
+struct mboot_tag_new_rsdp {
+ mboot_uint32_t type;
mboot_uint32_t size;
- mboot_uint8_t xsdp[];
+ mboot_uint8_t rsdp[];
};
-struct mboot_cmdline {
- mboot_uint32_t tag;
+struct mboot_tag_cmdline {
+ mboot_uint32_t type;
mboot_uint32_t size;
- char cmdline[];
+ mboot_uint8_t cmdline[];
};
static void read_symbols(
struct boot_info *shim_info,
- struct mboot_elf_header_layout *layout
+ struct mboot_tag_elf_sections *sections
) {
- shim_info->symbol_table = layout->elf_section_headers;
+ shim_info->symbol_table = sections->sections;
// struct mboot_elf_section_header *section =
// (struct mboot_elf_section_header *) (layout->elf_section_headers);
@@ -130,7 +132,7 @@ static void read_symbols(
static void read_cmdline(
struct boot_info *shim_info,
- struct mboot_cmdline *cmdline
+ struct mboot_tag_cmdline *cmdline
) {
mboot_uint32_t size = cmdline->size - 8;
if (size >= CMDLINE_MAX)
@@ -139,39 +141,49 @@ static void read_cmdline(
shim_info->cmdline[size] = '\0';
}
-static void read_memorymap(
+static void read_memory_map(
struct boot_info *shim_info,
- struct mboot_memory_map *map
+ struct mboot_tag_mmap *map
) {
- int size = map->size - sizeof(mboot_uint32_t) * 4;
- int count = size / map->entry_size;
-
- shim_info->map.entry_count = count;
- shim_info->map.entry_length = map->entry_size;
- shim_info->map.entries = map->entries;
+ int idx = 0;
+ uintptr_t i = (uintptr_t)map->entries;
+ for ( ;
+ i < (uintptr_t)map->entries + map->size;
+ i += map->entry_size, idx++
+ ) {
+ struct mboot_mmap_entry *seg = (struct mboot_mmap_entry *) i;
+ shim_info->map.entries[idx].addr = seg->addr;
+ shim_info->map.entries[idx].type = seg->type;
+ shim_info->map.entries[idx].len = seg->len;
+ }
+ shim_info->map.entry_count = idx;
}
-static void read_rsdp(
+static void read_old_rsdp(
struct boot_info *shim_info,
- struct mboot_rsdp *rsdp
+ struct mboot_tag_old_rsdp *rsdp
) {
if (shim_info->acpi_table != NULL)
return; // xsdp is newer and has been loaded
shim_info->acpi_table = rsdp->rsdp;
}
-static void read_xsdp(
+static void read_new_rsdp(
struct boot_info *shim_info,
- struct mboot_xsdp *xsdp
+ struct mboot_tag_new_rsdp *rsdp
) {
- shim_info->acpi_table = xsdp->xsdp;
+ shim_info->acpi_table = rsdp->rsdp;
}
void mboot_load_info(
+ long mboot_magic,
const void *mboot_data_ptr,
struct boot_info *shim_info
) {
+ if (mboot_magic != MBOOT_HEADER_MAGIC)
+ panic("invalid multiboot magic");
+
memset(shim_info, 0, sizeof(struct boot_info));
struct mboot_info *mboot_info = (struct mboot_info *) mboot_data_ptr;
@@ -186,31 +198,31 @@ void mboot_load_info(
case MBOOT_CMDLINE:
read_cmdline(
shim_info,
- (struct mboot_cmdline *) tag
+ (struct mboot_tag_cmdline *) tag
);
break;
- case MBOOT_MEMORYMAP:
- read_memorymap(
+ case MBOOT_MEMORY_MAP:
+ read_memory_map(
shim_info,
- (struct mboot_memory_map *) tag
+ (struct mboot_tag_mmap *) tag
);
break;
- case MBOOT_SYMBOLS:
+ case MBOOT_ELF_SYMBOLS:
read_symbols(
shim_info,
- (struct mboot_elf_header_layout *) tag
+ (struct mboot_tag_elf_sections *) tag
);
break;
- case MBOOT_RSDP:
- read_rsdp(
+ case MBOOT_OLD_RSDP:
+ read_old_rsdp(
shim_info,
- (struct mboot_rsdp *) tag
+ (struct mboot_tag_old_rsdp *) tag
);
break;
- case MBOOT_XSDP:
- read_xsdp(
+ case MBOOT_NEW_RSDP:
+ read_new_rsdp(
shim_info,
- (struct mboot_xsdp *) tag
+ (struct mboot_tag_new_rsdp *) tag
);
break;
default:
diff --git a/src/arch/amd64/mboot.h b/src/arch/amd64/mboot.h
index 90ed75c..b9c647b 100644
--- a/src/arch/amd64/mboot.h
+++ b/src/arch/amd64/mboot.h
@@ -8,4 +8,4 @@
* @param mboot_info - the pointer passed from multiboot2
* @param shim_info - the info to be collected by shim
*/
-void mboot_load_info(const void *mboot_info, struct boot_info *shim_info);
+void mboot_load_info(long mboot_magic, const void *mboot_info, struct boot_info *shim_info);
diff --git a/src/arch/amd64/serial.c b/src/arch/amd64/serial.c
index 85cd408..d63d9dd 100644
--- a/src/arch/amd64/serial.c
+++ b/src/arch/amd64/serial.c
@@ -16,7 +16,7 @@ int serial_init(void) {
// outb(port + 4, 0x0B); // TODO copied this from osdev wiki but i don't think you need it here
outb(PORT + 4, 0x1E); // set in loopback mode for test
outb(PORT + 0, 0xAE); // test by sending 0xAE
-
+
uint8_t response = inb(PORT + 0);
if(response != 0xAE) {
// TODO panic here?
@@ -40,7 +40,7 @@ void serial_out(uint8_t ch) {
outb(PORT, ch);
}
-void serial_out_str(char *str) {
+void serial_out_str(const char *str) {
for(; *str != '\0'; str++) {
serial_out(*str);
}
diff --git a/src/arch/amd64/shim.c b/src/arch/amd64/shim.c
index 7332994..3c0bd72 100644
--- a/src/arch/amd64/shim.c
+++ b/src/arch/amd64/shim.c
@@ -11,14 +11,13 @@
static struct boot_info boot_info;
-void* amd64_shim(void *mboot_data_ptr) {
-
+void* amd64_shim(long mboot_magic, void *mboot_data_ptr) {
serial_init();
paging_init();
pic_remap();
idt_init();
- mboot_load_info(mboot_data_ptr, &boot_info);
+ mboot_load_info(mboot_magic, mboot_data_ptr, &boot_info);
return &boot_info;
}