diff options
Diffstat (limited to 'src/arch/amd64')
-rw-r--r-- | src/arch/amd64/acpi.c | 7 | ||||
-rw-r--r-- | src/arch/amd64/boot.S | 4 | ||||
-rw-r--r-- | src/arch/amd64/linker.ld | 38 | ||||
-rw-r--r-- | src/arch/amd64/mboot.c | 138 | ||||
-rw-r--r-- | src/arch/amd64/mboot.h | 2 | ||||
-rw-r--r-- | src/arch/amd64/serial.c | 4 | ||||
-rw-r--r-- | src/arch/amd64/shim.c | 5 |
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; } |