Full support for Multiboot2 booting, remove legacy loader
This commit is contained in:
+85
-8
@@ -19,29 +19,89 @@
|
||||
_entry64:
|
||||
.code32
|
||||
cli
|
||||
|
||||
// Store multiboot info before doing anything
|
||||
leal (multiboot_registers - 0xFFFFFF0000000000), %edi
|
||||
movl %eax, 0(%edi)
|
||||
movl %ebx, 4(%edi)
|
||||
|
||||
// Setup long mode
|
||||
// Enable PSE and PAE
|
||||
mov %cr4, %eax
|
||||
or $((1 << 5) | (1 << 4)), %eax
|
||||
mov %eax, %cr4
|
||||
|
||||
cli
|
||||
hlt
|
||||
// 0x1FF000 - PML4
|
||||
// 0x1FE000 - PDPT
|
||||
movl $0x1FE000, %ebx
|
||||
// Zero out the tables
|
||||
movl %ebx, %edi
|
||||
movl $0x800, %ecx
|
||||
xorl %eax, %eax
|
||||
cld
|
||||
rep stosl
|
||||
|
||||
// Setup PML4
|
||||
// PDPT | present | write
|
||||
orl $((1 << 1) | (1 << 0)), %ebx
|
||||
// PML4[0] -> ...
|
||||
movl $0x1FF000, %edi
|
||||
movl %ebx, (%edi)
|
||||
// PML4[510] -> ...
|
||||
movl $0x1FFFF0, %edi
|
||||
movl %ebx, (%edi)
|
||||
|
||||
// Setup PDPT
|
||||
movl $0x1FE000, %edi
|
||||
movl $0, %ecx
|
||||
.setup_pdpt_loop:
|
||||
1:
|
||||
// PDPT[i] = (i << 30) | write | present | huge | global
|
||||
movl %ecx, %edx
|
||||
shl $30, %edx
|
||||
orl $((1 << 7) | (1 << 1) | (1 << 0)), %edx
|
||||
movl %edx, (%edi, %ecx, 8)
|
||||
|
||||
incl %ecx
|
||||
cmpl $4, %ecx
|
||||
jne 1b
|
||||
|
||||
// Load PML4 into CR3
|
||||
movl $0x1FF000, %eax
|
||||
movl %eax, %cr3
|
||||
|
||||
// Enable EFER.LME
|
||||
mov $0xC0000080, %ecx
|
||||
rdmsr
|
||||
or $(1 << 8), %eax
|
||||
wrmsr
|
||||
|
||||
// Enable paging
|
||||
mov %cr0, %eax
|
||||
or $(1 << 31), %eax
|
||||
mov %eax, %cr0
|
||||
|
||||
// Load 64-bit GDT
|
||||
// Have to fix up the addresses because not in 64-bit mode yet
|
||||
lgdt (gdtr64 - 0xFFFFFF0000000000)
|
||||
ljmp $0x08, $(.long_reload - 0xFFFFFF0000000000)
|
||||
.long_reload:
|
||||
mov $0x10, %ax
|
||||
mov %ax, %ds
|
||||
mov %ax, %es
|
||||
mov %ax, %fs
|
||||
mov %ax, %gs
|
||||
mov %ax, %ss
|
||||
|
||||
.code64
|
||||
// Full 64-bit now
|
||||
leaq kernel_stacks_bottom(%rip), %rsp
|
||||
addq $AMD64_KERNEL_STACK, %rsp
|
||||
|
||||
cli
|
||||
hlt
|
||||
|
||||
movq %rdi, %rbx
|
||||
call _init
|
||||
movq %rbx, %rdi
|
||||
|
||||
cli
|
||||
hlt
|
||||
|
||||
xorq %rbp, %rbp
|
||||
pushq %rbp
|
||||
call kernel_main
|
||||
@@ -52,10 +112,27 @@ _entry64:
|
||||
jmp 1b
|
||||
.size _entry64, . - _entry64
|
||||
|
||||
.code32
|
||||
.align 16
|
||||
gdt64:
|
||||
.quad 0
|
||||
.quad 0x00209A0000000000
|
||||
.quad 0x0000920000000000
|
||||
gdt_end64:
|
||||
.align 16
|
||||
gdtr64:
|
||||
.short gdt_end64 - gdt64 - 1
|
||||
.long gdt64 - 0xFFFFFF0000000000
|
||||
|
||||
// Entrypoint for AP bootstrap code
|
||||
.global kernel_stacks_top
|
||||
.global multiboot_registers
|
||||
|
||||
.section .bss
|
||||
multiboot_registers:
|
||||
// %eax - Magic
|
||||
// %ebx - Multiboot2 struct phys addr
|
||||
.skip 8
|
||||
kernel_stacks_bottom:
|
||||
#if defined(AMD64_SMP)
|
||||
.skip AMD64_KERNEL_STACK * AMD64_MAX_SMP
|
||||
|
||||
+65
-17
@@ -1,3 +1,4 @@
|
||||
#include "arch/amd64/multiboot2.h"
|
||||
#include "arch/amd64/hw/rs232.h"
|
||||
#include "arch/amd64/hw/vesa.h"
|
||||
#include "arch/amd64/hw/apic.h"
|
||||
@@ -20,35 +21,81 @@
|
||||
#include "sys/panic.h"
|
||||
#include "sys/mm.h"
|
||||
|
||||
static multiboot_info_t *multiboot_info;
|
||||
static uintptr_t multiboot_info_addr;
|
||||
static struct multiboot_tag_mmap *multiboot_tag_mmap;
|
||||
static struct multiboot_tag_module *multiboot_tag_initrd_module;
|
||||
static struct multiboot_tag_string *multiboot_tag_cmdline;
|
||||
|
||||
extern struct {
|
||||
uint32_t eax, ebx;
|
||||
} __attribute__((packed)) multiboot_registers;
|
||||
|
||||
static void amd64_make_random_seed(void) {
|
||||
random_init(15267 + system_time);
|
||||
}
|
||||
|
||||
void kernel_early_init(struct amd64_loader_data *data) {
|
||||
cpuid_init();
|
||||
data = (struct amd64_loader_data *) MM_VIRTUALIZE(data);
|
||||
multiboot_info = (multiboot_info_t *) MM_VIRTUALIZE(data->multiboot_info_ptr);
|
||||
void kernel_early_init(void) {
|
||||
// Check Multiboot2 signature
|
||||
if (multiboot_registers.eax != MULTIBOOT2_BOOTLOADER_MAGIC) {
|
||||
panic("Invalid bootloader magic\n");
|
||||
}
|
||||
multiboot_info_addr = MM_VIRTUALIZE(multiboot_registers.ebx);
|
||||
|
||||
if (data->symtab_ptr) {
|
||||
kinfo("Kernel symbol table at %p\n", MM_VIRTUALIZE(data->symtab_ptr));
|
||||
debug_symbol_table_set(MM_VIRTUALIZE(data->symtab_ptr), MM_VIRTUALIZE(data->strtab_ptr), data->symtab_size, data->strtab_size);
|
||||
// Find all requested tags
|
||||
uint32_t multiboot_len = *(uint32_t *) multiboot_info_addr;
|
||||
size_t offset = 8; // Skip 2 fields
|
||||
while (offset < multiboot_len) {
|
||||
struct multiboot_tag *tag = (struct multiboot_tag *) (multiboot_info_addr + offset);
|
||||
|
||||
if (tag->type == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (tag->type) {
|
||||
case MULTIBOOT_TAG_TYPE_CMDLINE:
|
||||
multiboot_tag_cmdline = (struct multiboot_tag_string *) tag;
|
||||
break;
|
||||
case MULTIBOOT_TAG_TYPE_MMAP:
|
||||
multiboot_tag_mmap = (struct multiboot_tag_mmap *) tag;
|
||||
break;
|
||||
case MULTIBOOT_TAG_TYPE_MODULE:
|
||||
multiboot_tag_initrd_module = (struct multiboot_tag_module *) tag;
|
||||
break;
|
||||
default:
|
||||
kdebug("tag.type = %u, tag.size = %u\n", tag->type, tag->size);
|
||||
break;
|
||||
}
|
||||
|
||||
offset += (tag->size + 7) & ~7;
|
||||
}
|
||||
|
||||
// Parse kernel command line
|
||||
kernel_set_cmdline(data->cmdline);
|
||||
if (!multiboot_tag_mmap) {
|
||||
panic("Multiboot2 loader provided no memory map\n");
|
||||
}
|
||||
|
||||
cpuid_init();
|
||||
|
||||
// TODO: use "ELF symbols" tag to get this info
|
||||
//if (data->symtab_ptr) {
|
||||
// kinfo("Kernel symbol table at %p\n", MM_VIRTUALIZE(data->symtab_ptr));
|
||||
// debug_symbol_table_set(MM_VIRTUALIZE(data->symtab_ptr), MM_VIRTUALIZE(data->strtab_ptr), data->symtab_size, data->strtab_size);
|
||||
//}
|
||||
|
||||
if (multiboot_tag_cmdline) {
|
||||
// Set kernel command line
|
||||
kinfo("Provided command line: \"%s\"\n", multiboot_tag_cmdline->string);
|
||||
kernel_set_cmdline(multiboot_tag_cmdline->string);
|
||||
}
|
||||
|
||||
// Reinitialize RS232 properly
|
||||
rs232_init(RS232_COM1);
|
||||
ps2_init();
|
||||
|
||||
amd64_phys_memory_map((multiboot_memory_map_t *) MM_VIRTUALIZE(multiboot_info->mmap_addr),
|
||||
multiboot_info->mmap_length);
|
||||
amd64_phys_memory_map(multiboot_tag_mmap);
|
||||
|
||||
amd64_gdt_init();
|
||||
amd64_idt_init(0);
|
||||
amd64_mm_init(data);
|
||||
amd64_mm_init();
|
||||
|
||||
ps2_register_device();
|
||||
|
||||
@@ -71,9 +118,10 @@ void kernel_early_init(struct amd64_loader_data *data) {
|
||||
t.tm_year, t.tm_mon, t.tm_mday,
|
||||
t.tm_hour, t.tm_min, t.tm_sec);
|
||||
|
||||
if (data->initrd_ptr) {
|
||||
if (multiboot_tag_initrd_module) {
|
||||
// Create ram0 block device
|
||||
ramblk_init(MM_VIRTUALIZE(data->initrd_ptr), data->initrd_len);
|
||||
ramblk_init(MM_VIRTUALIZE(multiboot_tag_initrd_module->mod_start),
|
||||
multiboot_tag_initrd_module->mod_end - multiboot_tag_initrd_module->mod_start);
|
||||
}
|
||||
|
||||
amd64_make_random_seed();
|
||||
@@ -85,7 +133,7 @@ void kernel_early_init(struct amd64_loader_data *data) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void kernel_main(struct amd64_loader_data *data) {
|
||||
kernel_early_init(data);
|
||||
void kernel_main(void) {
|
||||
kernel_early_init();
|
||||
main();
|
||||
}
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
.set ALIGN, 1 << 0
|
||||
.set MEMINFO, 1 << 1
|
||||
.set VIDEO, 1 << 2
|
||||
#if defined(VESA_ENABLE)
|
||||
.set FLAGS, ALIGN | VIDEO | MEMINFO
|
||||
#else
|
||||
.set FLAGS, ALIGN | MEMINFO
|
||||
#endif
|
||||
.set MAGIC, 0x1BADB002
|
||||
.set CHECKSUM, -(MAGIC + FLAGS)
|
||||
|
||||
.section .multiboot
|
||||
.align 4
|
||||
.long MAGIC
|
||||
.long FLAGS
|
||||
.long CHECKSUM
|
||||
.long 0 // header_addr
|
||||
.long 0 // load_addr
|
||||
.long 0 // load_end_addr
|
||||
.long 0 // bss_end_addr
|
||||
.long 0 // entry_addr
|
||||
#if defined(VESA_ENABLE)
|
||||
.long VESA_MODE
|
||||
.long VESA_WIDTH
|
||||
.long VESA_HEIGHT
|
||||
.long VESA_DEPTH
|
||||
#endif
|
||||
|
||||
.section .bss
|
||||
stack_bottom:
|
||||
.skip 65536
|
||||
stack_top:
|
||||
|
||||
.section .text
|
||||
.global _start
|
||||
_start:
|
||||
// Setup stack
|
||||
mov $stack_top, %esp
|
||||
|
||||
push %ebx
|
||||
push %eax
|
||||
|
||||
// Check if the CPU supports long mode
|
||||
mov $0x80000001, %eax
|
||||
cpuid
|
||||
test $(1 << 29), %edx
|
||||
jz .not_supported
|
||||
|
||||
call loader_main
|
||||
add $8, %esp
|
||||
|
||||
push $_msg_failure
|
||||
call panic
|
||||
add $4, %esp
|
||||
1:
|
||||
cli
|
||||
hlt
|
||||
jmp 1b
|
||||
.not_supported:
|
||||
push $_msg_not_supported
|
||||
call panic
|
||||
add $4, %esp
|
||||
jmp 1b
|
||||
|
||||
_msg_not_supported:
|
||||
.string "Long mode is not supported by the CPU"
|
||||
_msg_failure:
|
||||
.string "Unknown error"
|
||||
|
||||
.global long_entry
|
||||
long_entry:
|
||||
cli
|
||||
|
||||
// Enable PSE and PAE
|
||||
mov %cr4, %eax
|
||||
or $((1 << 5) | (1 << 4)), %eax
|
||||
mov %eax, %cr4
|
||||
|
||||
// Load PML4 address into cr3
|
||||
mov $pml4, %eax
|
||||
mov %eax, %cr3
|
||||
|
||||
// Enable EFER.LME
|
||||
mov $0xC0000080, %ecx
|
||||
rdmsr
|
||||
or $(1 << 8), %eax
|
||||
wrmsr
|
||||
|
||||
// Enable paging
|
||||
mov %cr0, %eax
|
||||
or $(1 << 31), %eax
|
||||
mov %eax, %cr0
|
||||
|
||||
// Load 64-bit GDT
|
||||
lgdt (gdtr64)
|
||||
ljmp $0x08, $.long_reload
|
||||
|
||||
.long_reload:
|
||||
mov $0x10, %ax
|
||||
mov %ax, %ds
|
||||
mov %ax, %es
|
||||
mov %ax, %fs
|
||||
mov %ax, %gs
|
||||
mov %ax, %ss
|
||||
|
||||
.code64
|
||||
leaq loader_data(%rip), %rdi
|
||||
movq 4(%rsp), %rax
|
||||
jmp *%rax
|
||||
.code32
|
||||
|
||||
.align 16
|
||||
gdt64:
|
||||
.quad 0
|
||||
.quad 0x00209A0000000000
|
||||
.quad 0x0000920000000000
|
||||
gdt_end64:
|
||||
.align 16
|
||||
gdtr64:
|
||||
.short gdt_end64 - gdt64 - 1
|
||||
.long gdt64
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* amd64 loader linker script
|
||||
* (this is not kernel)
|
||||
*/
|
||||
|
||||
ENTRY(_start)
|
||||
|
||||
SECTIONS {
|
||||
. = 0x100000;
|
||||
|
||||
_loader_start = .;
|
||||
|
||||
.text : ALIGN(4K)
|
||||
{
|
||||
*(.multiboot)
|
||||
*(.text)
|
||||
}
|
||||
|
||||
.rodata : ALIGN(4K)
|
||||
{
|
||||
*(.rodata)
|
||||
}
|
||||
|
||||
.data : ALIGN(4K)
|
||||
{
|
||||
*(.data)
|
||||
}
|
||||
|
||||
.bss : ALIGN(4K)
|
||||
{
|
||||
*(COMMON)
|
||||
*(.bss)
|
||||
}
|
||||
|
||||
_loader_end = .;
|
||||
}
|
||||
@@ -1,191 +0,0 @@
|
||||
#include "arch/amd64/loader/multiboot.h"
|
||||
#include "arch/amd64/loader/util.h"
|
||||
#include "arch/amd64/loader/data.h"
|
||||
#include "arch/amd64/loader/elf.h"
|
||||
|
||||
#define KERNEL_VIRT_BASE 0xFFFFFF0000000000
|
||||
|
||||
extern void long_entry(uint64_t v);
|
||||
|
||||
struct amd64_loader_data loader_data;
|
||||
uint64_t pml4[512] __attribute__((aligned(0x1000)));
|
||||
static uint64_t loader_pdpt[512] __attribute__((aligned(0x1000)));
|
||||
static uint64_t kernel_pdpt[512] __attribute__((aligned(0x1000)));
|
||||
|
||||
static uintptr_t modules_end = 0;
|
||||
static uintptr_t loader_end;
|
||||
extern uintptr_t _loader_end; // Linker
|
||||
|
||||
static void paging_init(void) {
|
||||
// 0x0000000000000000 - 0x0000000040000000 - loader, 1GiB
|
||||
pml4[0] = (uint64_t) (uintptr_t) loader_pdpt | 1 | 2;
|
||||
loader_pdpt[0] = 1 | 2 | (1 << 7);
|
||||
|
||||
// 0xFFFFFF0000000000 - 0xFFFFFF0040000000 - kernel, 1GiB
|
||||
pml4[(KERNEL_VIRT_BASE & 0xFFFFFFFFFFFF) >> 39] = (uint64_t) (uintptr_t) kernel_pdpt | 1 | 2;
|
||||
kernel_pdpt[0] = 1 | 2 | (1 << 7);
|
||||
}
|
||||
|
||||
static uint64_t elf_load(uintptr_t src) {
|
||||
Elf64_Ehdr *ehdr = (Elf64_Ehdr *) src;
|
||||
|
||||
// Validate magic
|
||||
if (ehdr->e_ident[EI_MAG0] != ELFMAG0 ||
|
||||
ehdr->e_ident[EI_MAG1] != ELFMAG1 ||
|
||||
ehdr->e_ident[EI_MAG2] != ELFMAG2 ||
|
||||
ehdr->e_ident[EI_MAG3] != ELFMAG3) {
|
||||
panic("Invalid ELF magic");
|
||||
}
|
||||
|
||||
// Validate target platform
|
||||
if (ehdr->e_ident[EI_CLASS] != ELFCLASS64) {
|
||||
panic("This image was not intended to run on amd64");
|
||||
}
|
||||
|
||||
Elf64_Shdr *shdrs = (Elf64_Shdr *) (src + (uintptr_t) ehdr->e_shoff);
|
||||
const char *shstrtabd = (const char *) (src + (uintptr_t) shdrs[ehdr->e_shstrndx].sh_offset);
|
||||
|
||||
loader_data.strtab_ptr = 0;
|
||||
loader_data.strtab_size = 0;
|
||||
loader_data.symtab_ptr = 0;
|
||||
loader_data.symtab_size = 0;
|
||||
|
||||
for (size_t i = 0; i < (size_t) ehdr->e_shnum; ++i) {
|
||||
Elf64_Shdr *shdr = &shdrs[i];
|
||||
const char *name = &shstrtabd[shdr->sh_name];
|
||||
|
||||
if (shdr->sh_type == SHT_SYMTAB && !strcmp(name, ".symtab")) {
|
||||
loader_data.symtab_ptr = (uint32_t) shdr->sh_offset + src;
|
||||
loader_data.symtab_size = (uint32_t) shdr->sh_size;
|
||||
}
|
||||
|
||||
if (shdr->sh_type == SHT_STRTAB && !strcmp(name, ".strtab")) {
|
||||
puts("Strtab section: ");
|
||||
puts(name);
|
||||
putc('\n');
|
||||
|
||||
loader_data.strtab_ptr = (uint32_t) shdr->sh_offset + src;
|
||||
loader_data.strtab_size = (uint32_t) shdr->sh_size;
|
||||
}
|
||||
|
||||
if (shdr->sh_flags & SHF_ALLOC) {
|
||||
if (!strcmp(name, ".note.gnu.property")) {
|
||||
// Fuck you, gcc
|
||||
continue;
|
||||
}
|
||||
|
||||
uint64_t phys_addr = shdr->sh_addr - KERNEL_VIRT_BASE;
|
||||
puts("Section ");
|
||||
puts(name);
|
||||
putc('\n');
|
||||
puts("\tPhysical address: ");
|
||||
putx(phys_addr);
|
||||
putc('\n');
|
||||
|
||||
if (phys_addr < loader_end || phys_addr < modules_end) {
|
||||
panic("Physical load address is too low: may overwrite modules");
|
||||
}
|
||||
|
||||
if (shdr->sh_type == SHT_NOBITS) {
|
||||
memset((void *) (uintptr_t) phys_addr, 0, (size_t) shdr->sh_size);
|
||||
} else if (shdr->sh_type == SHT_PROGBITS) {
|
||||
memcpy((void *) (uintptr_t) phys_addr, (const void *) (src + (uintptr_t) shdr->sh_offset), (size_t) shdr->sh_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
puts("Entry: ");
|
||||
putx(ehdr->e_entry);
|
||||
putc('\n');
|
||||
|
||||
return ehdr->e_entry;
|
||||
}
|
||||
|
||||
void loader_main(uint32_t magic, struct multiboot_info *mb_info) {
|
||||
if (magic != MULTIBOOT_BOOTLOADER_MAGIC) {
|
||||
panic("Invalid bootloader magic");
|
||||
}
|
||||
|
||||
// Setup loader_data
|
||||
loader_data.multiboot_info_ptr = (uintptr_t) mb_info;
|
||||
|
||||
struct multiboot_mod_list *mod_list = (struct multiboot_mod_list *) (uintptr_t) mb_info->mods_addr;
|
||||
char *kernel_cmdline = NULL;
|
||||
uintptr_t kernel_mod = 0;
|
||||
uintptr_t initrd_mod = 0;
|
||||
|
||||
loader_data.initrd_ptr = 0;
|
||||
loader_data.initrd_len = 0;
|
||||
|
||||
if (mb_info->mods_count == 1) {
|
||||
// Only kernel is provided, ignore cmdline
|
||||
kernel_mod = mod_list[0].mod_start;
|
||||
} else if (mb_info->mods_count == 2) {
|
||||
// initrd and kernel provided
|
||||
// Find out which is which
|
||||
|
||||
for (size_t i = 0; i < mb_info->mods_count; ++i) {
|
||||
if (!strncmp((const char *) (uintptr_t) mod_list[i].cmdline, "kernel", 6)) {
|
||||
if (kernel_mod) {
|
||||
panic("Two \"kernel\"s provided!");
|
||||
}
|
||||
kernel_mod = mod_list[i].mod_start;
|
||||
kernel_cmdline = (char *) (uintptr_t) mod_list[i].cmdline;
|
||||
} else {
|
||||
if (initrd_mod) {
|
||||
panic("Two \"initrd\"s provided!");
|
||||
}
|
||||
initrd_mod = mod_list[i].mod_start;
|
||||
|
||||
loader_data.initrd_len = mod_list[i].mod_end - mod_list[i].mod_start;
|
||||
loader_data.initrd_ptr = mod_list[i].mod_start;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
panic("More than two modules provided");
|
||||
}
|
||||
|
||||
if (!kernel_mod) {
|
||||
panic("No kernel to load");
|
||||
}
|
||||
|
||||
// Calculate boundaries so we don't overwrite something accidentally
|
||||
for (size_t i = 0; i < mb_info->mods_count; ++i) {
|
||||
if (mod_list[i].mod_end > modules_end) {
|
||||
modules_end = mod_list[i].mod_end;
|
||||
}
|
||||
}
|
||||
|
||||
if (kernel_cmdline) {
|
||||
if (strlen(kernel_cmdline) >= KERNEL_CMDLINE_MAX) {
|
||||
kernel_cmdline[KERNEL_CMDLINE_MAX - 1] = 0;
|
||||
}
|
||||
strcpy(loader_data.cmdline, kernel_cmdline);
|
||||
|
||||
puts("Kernel cmdline: ");
|
||||
puts(kernel_cmdline);
|
||||
putc('\n');
|
||||
} else {
|
||||
loader_data.cmdline[0] = 0;
|
||||
}
|
||||
puts("Modules end addr: ");
|
||||
putx(modules_end);
|
||||
putc('\n');
|
||||
loader_end = (uintptr_t) &_loader_end;
|
||||
puts("Loader end addr: ");
|
||||
putx(loader_end);
|
||||
putc('\n');
|
||||
|
||||
paging_init();
|
||||
|
||||
uint64_t entry = elf_load(mod_list[0].mod_start);
|
||||
|
||||
// Calculate checksum for loader_data
|
||||
uint8_t checksum = 0;
|
||||
for (size_t i = 0; i < sizeof(struct amd64_loader_data) - sizeof(uint8_t); ++i) {
|
||||
checksum += ((uint8_t *) &loader_data)[i];
|
||||
}
|
||||
loader_data.checksum = -checksum;
|
||||
|
||||
long_entry(entry);
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
#include "arch/amd64/loader/util.h"
|
||||
|
||||
void *memset(void *blk, int v, size_t sz) {
|
||||
for (size_t i = 0; i < sz; ++i) {
|
||||
((char *) blk)[i] = v;
|
||||
}
|
||||
return blk;
|
||||
}
|
||||
|
||||
void *memcpy(void *dst, const void *src, size_t sz) {
|
||||
for (size_t i = 0; i < sz; ++i) {
|
||||
((char *) dst)[i] = ((const char *) src)[i];
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
size_t strlen(const char *s) {
|
||||
size_t r;
|
||||
for (r = 0; *s; ++s, ++r);
|
||||
return r;
|
||||
}
|
||||
|
||||
char *strcpy(char *dst, const char *src) {
|
||||
char *r = dst;
|
||||
for (; *src; ++src, ++dst) {
|
||||
*dst = *src;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
int strcmp(const char *a, const char *b) {
|
||||
for (; *a && *b; ++a, ++b) {
|
||||
if (*a != *b) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return *a != *b;
|
||||
}
|
||||
|
||||
int strncmp(const char *a, const char *b, size_t n) {
|
||||
size_t c = 0;
|
||||
for (; c < n && (*a || *b); ++c, ++a, ++b) {
|
||||
if (*a != *b) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void outb(uint16_t addr, uint8_t v) {
|
||||
asm volatile("outb %0, %1"::"a"(v), "Nd"(addr));
|
||||
}
|
||||
|
||||
static inline uint8_t inb(uint16_t addr) {
|
||||
uint8_t v;
|
||||
asm volatile("inb %1, %0":"=a"(v):"Nd"(addr));
|
||||
return v;
|
||||
}
|
||||
|
||||
void putc(char c) {
|
||||
while (!(inb(0x3F8 + 5) & 0x20)) {}
|
||||
outb(0x3F8, c);
|
||||
}
|
||||
|
||||
void puts(const char *s) {
|
||||
for (; *s; ++s) {
|
||||
putc(*s);
|
||||
}
|
||||
}
|
||||
|
||||
void putx(uint64_t v) {
|
||||
static const char *set = "0123456789abcdef";
|
||||
char buf[32];
|
||||
memset(buf, 0, sizeof(buf));
|
||||
if (!v) {
|
||||
puts("0x0");
|
||||
return;
|
||||
}
|
||||
|
||||
int c = 0;
|
||||
|
||||
while (v) {
|
||||
buf[c++] = set[v & 0xF];
|
||||
v >>= 4;
|
||||
}
|
||||
|
||||
buf[c] = 0;
|
||||
|
||||
for (int i = 0, j = c - 1; i < j; ++i, --j) {
|
||||
buf[i] ^= buf[j];
|
||||
buf[j] ^= buf[i];
|
||||
buf[i] ^= buf[j];
|
||||
}
|
||||
|
||||
puts("0x");
|
||||
puts(buf);
|
||||
}
|
||||
|
||||
void panic(const char *s) {
|
||||
memset((void *) 0xB8000, 0, 80 * 25 * 2);
|
||||
puts(s);
|
||||
|
||||
for (size_t i = 0; *s; ++i, ++s) {
|
||||
((uint16_t *) 0xB8000)[i] = *s | 0x700;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
asm volatile ("cli; hlt");
|
||||
}
|
||||
}
|
||||
+2
-37
@@ -21,7 +21,7 @@ void userptr_check(const void *ptr) {
|
||||
assert((uintptr_t) ptr < KERNEL_VIRT_BASE, "invalid userptr: in kernel space (%p)\n", ptr);
|
||||
}
|
||||
|
||||
void amd64_mm_init(struct amd64_loader_data *data) {
|
||||
void amd64_mm_init(void) {
|
||||
kdebug("Memory manager init\n");
|
||||
|
||||
// TODO: restore NX and do it per-CPU
|
||||
@@ -36,45 +36,10 @@ void amd64_mm_init(struct amd64_loader_data *data) {
|
||||
// wrmsr(MSR_IA32_EFER, efer);
|
||||
//}
|
||||
|
||||
// Physical memory at this point:
|
||||
// 0x000000 - 0x400000 - Used by kernel and info passed from the loader
|
||||
// Virtual memory:
|
||||
// Lower 1GiB mapped to itself for loader access
|
||||
// 0xFFFFFF0000000000 (1GiB) is mapped to 0 for kernel access
|
||||
|
||||
// XXX: assuming nothing important is there
|
||||
uint64_t *pml4 = (uint64_t *) (0x200000 - 0x1000);
|
||||
uint64_t *pdpt = (uint64_t *) (0x200000 - 0x2000);
|
||||
|
||||
memset((void *) (0x200000 - 2 * 0x1000), 0, 0x1000 * 2);
|
||||
|
||||
// 0x0000000000000000 -> 0 Mapping for AP bootstrapping
|
||||
// pml4[0] = ((uintptr_t) pdpt) | 1 | 2 | 4;
|
||||
// 0xFFFFFF0000000000 -> 0 (512GiB) mapping
|
||||
pml4[0] = ((uintptr_t) pdpt) |
|
||||
MM_PAGE_PRESENT |
|
||||
MM_PAGE_WRITE;
|
||||
pml4[AMD64_MM_STRIPSX(KERNEL_VIRT_BASE) >> 39] = ((uintptr_t) pdpt) |
|
||||
MM_PAGE_PRESENT |
|
||||
MM_PAGE_WRITE;
|
||||
for (uint64_t i = 0; i < 4; ++i) {
|
||||
kdebug("Mapping %p -> %p\n", KERNEL_VIRT_BASE | (i << 30), i << 30);
|
||||
pdpt[((AMD64_MM_STRIPSX(KERNEL_VIRT_BASE) >> 30) + i) & 0x1FF] = (i << 30) |
|
||||
MM_PAGE_WRITE |
|
||||
MM_PAGE_GLOBAL |
|
||||
MM_PAGE_PRESENT |
|
||||
MM_PAGE_HUGE;
|
||||
}
|
||||
|
||||
// Load the new table
|
||||
asm volatile ("movq %0, %%cr3"::"a"(pml4):"memory");
|
||||
|
||||
mm_kernel = (mm_space_t) (MM_VIRTUALIZE(0x1FF000));
|
||||
// Create a pool located right after kernel image
|
||||
amd64_mm_pool_init((uintptr_t) &_kernel_end, MM_POOL_SIZE);
|
||||
|
||||
mm_kernel = (mm_space_t) (MM_VIRTUALIZE(pml4));
|
||||
|
||||
// // Allocate some pages for kernel heap (base size: 16MiB)
|
||||
uintptr_t heap_base_phys = mm_phys_alloc_contiguous(KERNEL_HEAP >> 12);
|
||||
assert(heap_base_phys != MM_NADDR, "Could not allocate %S of memory for kernel heap\n", KERNEL_HEAP);
|
||||
kdebug("Setting up kernel heap of %S @ %p\n", KERNEL_HEAP, heap_base_phys);
|
||||
|
||||
@@ -71,20 +71,21 @@ static void phys_add_page(size_t index) {
|
||||
_pages[index].refcount = 0;
|
||||
}
|
||||
|
||||
void amd64_phys_memory_map(const multiboot_memory_map_t *mmap, size_t length) {
|
||||
//kdebug("Kernel table pool ends @ %p\n", PHYS_ALLOWED_BEGIN);
|
||||
void amd64_phys_memory_map(const struct multiboot_tag_mmap *mmap) {
|
||||
kdebug("Kernel table pool ends @ %p\n", PHYS_ALLOWED_BEGIN);
|
||||
kdebug("Memory map @ %p\n", mmap);
|
||||
uintptr_t curr_item = (uintptr_t) mmap;
|
||||
uintptr_t mmap_end = length + curr_item;
|
||||
|
||||
size_t item_offset = offsetof(struct multiboot_tag_mmap, entries);
|
||||
|
||||
memset(_pages, 0xFF, sizeof(_pages));
|
||||
_total_pages = 0;
|
||||
_alloc_pages = 0;
|
||||
|
||||
// Collect usable physical memory information
|
||||
while (curr_item < mmap_end) {
|
||||
const multiboot_memory_map_t *entry = (const multiboot_memory_map_t *) (curr_item);
|
||||
|
||||
while (item_offset < mmap->size) {
|
||||
//const multiboot_memory_map_t *entry = (const multiboot_memory_map_t *) (curr_item);
|
||||
const struct multiboot_mmap_entry *entry =
|
||||
(const struct multiboot_mmap_entry *) ((uintptr_t) mmap + item_offset);
|
||||
uintptr_t page_aligned_begin = MAX((entry->addr + 0xFFF) & ~0xFFF, PHYS_ALLOWED_BEGIN);
|
||||
uintptr_t page_aligned_end = (entry->addr + entry->len) & ~0xFFF;
|
||||
|
||||
@@ -100,7 +101,7 @@ void amd64_phys_memory_map(const multiboot_memory_map_t *mmap, size_t length) {
|
||||
}
|
||||
}
|
||||
|
||||
curr_item += entry->size + sizeof(uint32_t);
|
||||
item_offset += mmap->entry_size;
|
||||
}
|
||||
|
||||
kdebug("%S available\n", _total_pages << 12);
|
||||
|
||||
+1
-32
@@ -6,7 +6,7 @@ include etc/make/amd64/config.mk
|
||||
|
||||
all:
|
||||
|
||||
TARGETS+=$(O)/loader.elf $(O)/kernel.elf
|
||||
TARGETS+=$(O)/kernel.elf
|
||||
|
||||
# add .inc includes for asm
|
||||
HEADERS+=$(shell find include -name "*.inc")
|
||||
@@ -46,34 +46,3 @@ $(O)/sys/font/%.o: etc/%.psfu config
|
||||
-DINCBIN_START="_psf_start" \
|
||||
-DINCBIN_END="_psf_end" \
|
||||
-o $@ arch/amd64/incbin.S
|
||||
|
||||
### Kernel loader build
|
||||
DIRS+=$(O)/arch/amd64/loader
|
||||
loader_OBJS+=$(O)/arch/amd64/loader/boot.o \
|
||||
$(O)/arch/amd64/loader/loader.o \
|
||||
$(O)/arch/amd64/loader/util.o
|
||||
loader_LINKER=arch/amd64/loader/link.ld
|
||||
loader_CFLAGS=-ffreestanding \
|
||||
-nostdlib \
|
||||
-I. \
|
||||
-Iinclude \
|
||||
-Wall \
|
||||
-Wextra \
|
||||
-Wpedantic \
|
||||
-Wno-unused-argument \
|
||||
-Werror \
|
||||
-Wno-language-extension-token \
|
||||
-D__KERNEL__
|
||||
loader_LDFLAGS=-nostdlib -T$(loader_LINKER)
|
||||
|
||||
$(O)/loader.elf: $(loader_OBJS) $(loader_LINKER) config
|
||||
@printf " LD\t%s\n" $(@:$(O)/%=%)
|
||||
@$(CC86) $(loader_LDFLAGS) -o $@ $(loader_OBJS)
|
||||
|
||||
$(O)/arch/amd64/loader/%.o: arch/amd64/loader/%.S $(HEADERS) config
|
||||
@printf " AS\t%s\n" $(@:$(O)/%=%)
|
||||
@$(CC86) $(loader_CFLAGS) $(DEFINES) -D__ASM__ -c -o $@ $<
|
||||
|
||||
$(O)/arch/amd64/loader/%.o: arch/amd64/loader/%.c $(HEADERS) config
|
||||
@printf " CC\t%s\n" $(@:$(O)/%=%)
|
||||
@$(CC86) $(loader_CFLAGS) $(DEFINES) -c -o $@ $<
|
||||
|
||||
@@ -8,8 +8,7 @@ ACPICA_OBJS=$(ACPICA_SRCS:%.c=$(O)/%.o)
|
||||
ACPICA_SRCD=$(shell find arch/amd64/acpica -type d)
|
||||
ACPICA_OBJD=$(ACPICA_SRCD:%=$(O)/%)
|
||||
|
||||
OBJS+=$(O)/arch/amd64/entry64.o \
|
||||
$(ACPICA_OBJS) \
|
||||
OBJS+=$(ACPICA_OBJS) \
|
||||
$(O)/arch/amd64/acpi_osl_mem.o \
|
||||
$(O)/arch/amd64/acpi_osl_printf.o \
|
||||
$(O)/arch/amd64/acpi_osl_thread.o \
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#pragma once
|
||||
#include "arch/amd64/loader/multiboot.h"
|
||||
#include "sys/types.h"
|
||||
|
||||
extern int vesa_available, vesa_hold;
|
||||
extern uint32_t vesa_width, vesa_height, vesa_pitch, vesa_bpp;
|
||||
extern uint64_t vesa_addr;
|
||||
|
||||
void amd64_vesa_init(multiboot_info_t *info);
|
||||
void vesa_put(uint32_t x, uint32_t y, uint32_t v);
|
||||
void vesa_clear(uint32_t color);
|
||||
//#pragma once
|
||||
//#include "arch/amd64/multiboot2.h"
|
||||
//#include "sys/types.h"
|
||||
//
|
||||
//extern int vesa_available, vesa_hold;
|
||||
//extern uint32_t vesa_width, vesa_height, vesa_pitch, vesa_bpp;
|
||||
//extern uint64_t vesa_addr;
|
||||
//
|
||||
//void amd64_vesa_init(multiboot_info_t *info);
|
||||
//void vesa_put(uint32_t x, uint32_t y, uint32_t v);
|
||||
//void vesa_clear(uint32_t color);
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
#define KERNEL_CMDLINE_MAX 256
|
||||
|
||||
struct amd64_loader_data {
|
||||
uint32_t multiboot_info_ptr;
|
||||
uint32_t symtab_ptr;
|
||||
uint32_t symtab_size;
|
||||
uint32_t strtab_ptr;
|
||||
uint32_t strtab_size;
|
||||
uint32_t initrd_ptr;
|
||||
uint32_t initrd_len;
|
||||
char cmdline[KERNEL_CMDLINE_MAX];
|
||||
// Just in case
|
||||
uint8_t checksum;
|
||||
} __attribute__((packed));
|
||||
@@ -1,443 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
#ifndef _UAPI_LINUX_ELF_H
|
||||
#define _UAPI_LINUX_ELF_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* 32-bit ELF base types. */
|
||||
typedef uint32_t Elf32_Addr;
|
||||
typedef uint16_t Elf32_Half;
|
||||
typedef uint32_t Elf32_Off;
|
||||
typedef uint32_t Elf32_Sword;
|
||||
typedef uint32_t Elf32_Word;
|
||||
|
||||
/* 64-bit ELF base types. */
|
||||
typedef uint64_t Elf64_Addr;
|
||||
typedef uint16_t Elf64_Half;
|
||||
typedef uint16_t Elf64_SHalf;
|
||||
typedef uint64_t Elf64_Off;
|
||||
typedef uint32_t Elf64_Sword;
|
||||
typedef uint32_t Elf64_Word;
|
||||
typedef uint64_t Elf64_Xword;
|
||||
typedef uint64_t Elf64_Sxword;
|
||||
|
||||
/* These constants are for the segment types stored in the image headers */
|
||||
#define PT_NULL 0
|
||||
#define PT_LOAD 1
|
||||
#define PT_DYNAMIC 2
|
||||
#define PT_INTERP 3
|
||||
#define PT_NOTE 4
|
||||
#define PT_SHLIB 5
|
||||
#define PT_PHDR 6
|
||||
#define PT_TLS 7 /* Thread local storage segment */
|
||||
#define PT_LOOS 0x60000000 /* OS-specific */
|
||||
#define PT_HIOS 0x6fffffff /* OS-specific */
|
||||
#define PT_LOPROC 0x70000000
|
||||
#define PT_HIPROC 0x7fffffff
|
||||
#define PT_GNU_EH_FRAME 0x6474e550
|
||||
|
||||
#define PT_GNU_STACK (PT_LOOS + 0x474e551)
|
||||
|
||||
/*
|
||||
* Extended Numbering
|
||||
*
|
||||
* If the real number of program header table entries is larger than
|
||||
* or equal to PN_XNUM(0xffff), it is set to sh_info field of the
|
||||
* section header at index 0, and PN_XNUM is set to e_phnum
|
||||
* field. Otherwise, the section header at index 0 is zero
|
||||
* initialized, if it exists.
|
||||
*
|
||||
* Specifications are available in:
|
||||
*
|
||||
* - Oracle: Linker and Libraries.
|
||||
* Part No: 817–1984–19, August 2011.
|
||||
* http://docs.oracle.com/cd/E18752_01/pdf/817-1984.pdf
|
||||
*
|
||||
* - System V ABI AMD64 Architecture Processor Supplement
|
||||
* Draft Version 0.99.4,
|
||||
* January 13, 2010.
|
||||
* http://www.cs.washington.edu/education/courses/cse351/12wi/supp-docs/abi.pdf
|
||||
*/
|
||||
#define PN_XNUM 0xffff
|
||||
|
||||
/* These constants define the different elf file types */
|
||||
#define ET_NONE 0
|
||||
#define ET_REL 1
|
||||
#define ET_EXEC 2
|
||||
#define ET_DYN 3
|
||||
#define ET_CORE 4
|
||||
#define ET_LOPROC 0xff00
|
||||
#define ET_HIPROC 0xffff
|
||||
|
||||
/* This is the info that is needed to parse the dynamic section of the file */
|
||||
#define DT_NULL 0
|
||||
#define DT_NEEDED 1
|
||||
#define DT_PLTRELSZ 2
|
||||
#define DT_PLTGOT 3
|
||||
#define DT_HASH 4
|
||||
#define DT_STRTAB 5
|
||||
#define DT_SYMTAB 6
|
||||
#define DT_RELA 7
|
||||
#define DT_RELASZ 8
|
||||
#define DT_RELAENT 9
|
||||
#define DT_STRSZ 10
|
||||
#define DT_SYMENT 11
|
||||
#define DT_INIT 12
|
||||
#define DT_FINI 13
|
||||
#define DT_SONAME 14
|
||||
#define DT_RPATH 15
|
||||
#define DT_SYMBOLIC 16
|
||||
#define DT_REL 17
|
||||
#define DT_RELSZ 18
|
||||
#define DT_RELENT 19
|
||||
#define DT_PLTREL 20
|
||||
#define DT_DEBUG 21
|
||||
#define DT_TEXTREL 22
|
||||
#define DT_JMPREL 23
|
||||
#define DT_ENCODING 32
|
||||
#define OLD_DT_LOOS 0x60000000
|
||||
#define DT_LOOS 0x6000000d
|
||||
#define DT_HIOS 0x6ffff000
|
||||
#define DT_VALRNGLO 0x6ffffd00
|
||||
#define DT_VALRNGHI 0x6ffffdff
|
||||
#define DT_ADDRRNGLO 0x6ffffe00
|
||||
#define DT_ADDRRNGHI 0x6ffffeff
|
||||
#define DT_VERSYM 0x6ffffff0
|
||||
#define DT_RELACOUNT 0x6ffffff9
|
||||
#define DT_RELCOUNT 0x6ffffffa
|
||||
#define DT_FLAGS_1 0x6ffffffb
|
||||
#define DT_VERDEF 0x6ffffffc
|
||||
#define DT_VERDEFNUM 0x6ffffffd
|
||||
#define DT_VERNEED 0x6ffffffe
|
||||
#define DT_VERNEEDNUM 0x6fffffff
|
||||
#define OLD_DT_HIOS 0x6fffffff
|
||||
#define DT_LOPROC 0x70000000
|
||||
#define DT_HIPROC 0x7fffffff
|
||||
|
||||
/* This info is needed when parsing the symbol table */
|
||||
#define STB_LOCAL 0
|
||||
#define STB_GLOBAL 1
|
||||
#define STB_WEAK 2
|
||||
|
||||
#define STT_NOTYPE 0
|
||||
#define STT_OBJECT 1
|
||||
#define STT_FUNC 2
|
||||
#define STT_SECTION 3
|
||||
#define STT_FILE 4
|
||||
#define STT_COMMON 5
|
||||
#define STT_TLS 6
|
||||
|
||||
#define ELF_ST_BIND(x) ((x) >> 4)
|
||||
#define ELF_ST_TYPE(x) (((unsigned int) x) & 0xf)
|
||||
#define ELF32_ST_BIND(x) ELF_ST_BIND(x)
|
||||
#define ELF32_ST_TYPE(x) ELF_ST_TYPE(x)
|
||||
#define ELF64_ST_BIND(x) ELF_ST_BIND(x)
|
||||
#define ELF64_ST_TYPE(x) ELF_ST_TYPE(x)
|
||||
|
||||
typedef struct dynamic{
|
||||
Elf32_Sword d_tag;
|
||||
union{
|
||||
Elf32_Sword d_val;
|
||||
Elf32_Addr d_ptr;
|
||||
} d_un;
|
||||
} Elf32_Dyn;
|
||||
|
||||
typedef struct {
|
||||
Elf64_Sxword d_tag; /* entry tag value */
|
||||
union {
|
||||
Elf64_Xword d_val;
|
||||
Elf64_Addr d_ptr;
|
||||
} d_un;
|
||||
} Elf64_Dyn;
|
||||
|
||||
/* The following are used with relocations */
|
||||
#define ELF32_R_SYM(x) ((x) >> 8)
|
||||
#define ELF32_R_TYPE(x) ((x) & 0xff)
|
||||
|
||||
#define ELF64_R_SYM(i) ((i) >> 32)
|
||||
#define ELF64_R_TYPE(i) ((i) & 0xffffffff)
|
||||
|
||||
typedef struct elf32_rel {
|
||||
Elf32_Addr r_offset;
|
||||
Elf32_Word r_info;
|
||||
} Elf32_Rel;
|
||||
|
||||
typedef struct elf64_rel {
|
||||
Elf64_Addr r_offset; /* Location at which to apply the action */
|
||||
Elf64_Xword r_info; /* index and type of relocation */
|
||||
} Elf64_Rel;
|
||||
|
||||
typedef struct elf32_rela{
|
||||
Elf32_Addr r_offset;
|
||||
Elf32_Word r_info;
|
||||
Elf32_Sword r_addend;
|
||||
} Elf32_Rela;
|
||||
|
||||
typedef struct elf64_rela {
|
||||
Elf64_Addr r_offset; /* Location at which to apply the action */
|
||||
Elf64_Xword r_info; /* index and type of relocation */
|
||||
Elf64_Sxword r_addend; /* Constant addend used to compute value */
|
||||
} Elf64_Rela;
|
||||
|
||||
typedef struct elf32_sym{
|
||||
Elf32_Word st_name;
|
||||
Elf32_Addr st_value;
|
||||
Elf32_Word st_size;
|
||||
unsigned char st_info;
|
||||
unsigned char st_other;
|
||||
Elf32_Half st_shndx;
|
||||
} Elf32_Sym;
|
||||
|
||||
typedef struct elf64_sym {
|
||||
Elf64_Word st_name; /* Symbol name, index in string tbl */
|
||||
unsigned char st_info; /* Type and binding attributes */
|
||||
unsigned char st_other; /* No defined meaning, 0 */
|
||||
Elf64_Half st_shndx; /* Associated section index */
|
||||
Elf64_Addr st_value; /* Value of the symbol */
|
||||
Elf64_Xword st_size; /* Associated symbol size */
|
||||
} Elf64_Sym;
|
||||
|
||||
|
||||
#define EI_NIDENT 16
|
||||
|
||||
typedef struct elf32_hdr{
|
||||
unsigned char e_ident[EI_NIDENT];
|
||||
Elf32_Half e_type;
|
||||
Elf32_Half e_machine;
|
||||
Elf32_Word e_version;
|
||||
Elf32_Addr e_entry; /* Entry point */
|
||||
Elf32_Off e_phoff;
|
||||
Elf32_Off e_shoff;
|
||||
Elf32_Word e_flags;
|
||||
Elf32_Half e_ehsize;
|
||||
Elf32_Half e_phentsize;
|
||||
Elf32_Half e_phnum;
|
||||
Elf32_Half e_shentsize;
|
||||
Elf32_Half e_shnum;
|
||||
Elf32_Half e_shstrndx;
|
||||
} Elf32_Ehdr;
|
||||
|
||||
typedef struct elf64_hdr {
|
||||
unsigned char e_ident[EI_NIDENT]; /* ELF "magic number" */
|
||||
Elf64_Half e_type;
|
||||
Elf64_Half e_machine;
|
||||
Elf64_Word e_version;
|
||||
Elf64_Addr e_entry; /* Entry point virtual address */
|
||||
Elf64_Off e_phoff; /* Program header table file offset */
|
||||
Elf64_Off e_shoff; /* Section header table file offset */
|
||||
Elf64_Word e_flags;
|
||||
Elf64_Half e_ehsize;
|
||||
Elf64_Half e_phentsize;
|
||||
Elf64_Half e_phnum;
|
||||
Elf64_Half e_shentsize;
|
||||
Elf64_Half e_shnum;
|
||||
Elf64_Half e_shstrndx;
|
||||
} Elf64_Ehdr;
|
||||
|
||||
/* These constants define the permissions on sections in the program
|
||||
header, p_flags. */
|
||||
#define PF_R 0x4
|
||||
#define PF_W 0x2
|
||||
#define PF_X 0x1
|
||||
|
||||
typedef struct elf32_phdr{
|
||||
Elf32_Word p_type;
|
||||
Elf32_Off p_offset;
|
||||
Elf32_Addr p_vaddr;
|
||||
Elf32_Addr p_paddr;
|
||||
Elf32_Word p_filesz;
|
||||
Elf32_Word p_memsz;
|
||||
Elf32_Word p_flags;
|
||||
Elf32_Word p_align;
|
||||
} Elf32_Phdr;
|
||||
|
||||
typedef struct elf64_phdr {
|
||||
Elf64_Word p_type;
|
||||
Elf64_Word p_flags;
|
||||
Elf64_Off p_offset; /* Segment file offset */
|
||||
Elf64_Addr p_vaddr; /* Segment virtual address */
|
||||
Elf64_Addr p_paddr; /* Segment physical address */
|
||||
Elf64_Xword p_filesz; /* Segment size in file */
|
||||
Elf64_Xword p_memsz; /* Segment size in memory */
|
||||
Elf64_Xword p_align; /* Segment alignment, file & memory */
|
||||
} Elf64_Phdr;
|
||||
|
||||
/* sh_type */
|
||||
#define SHT_NULL 0
|
||||
#define SHT_PROGBITS 1
|
||||
#define SHT_SYMTAB 2
|
||||
#define SHT_STRTAB 3
|
||||
#define SHT_RELA 4
|
||||
#define SHT_HASH 5
|
||||
#define SHT_DYNAMIC 6
|
||||
#define SHT_NOTE 7
|
||||
#define SHT_NOBITS 8
|
||||
#define SHT_REL 9
|
||||
#define SHT_SHLIB 10
|
||||
#define SHT_DYNSYM 11
|
||||
#define SHT_NUM 12
|
||||
#define SHT_LOPROC 0x70000000
|
||||
#define SHT_HIPROC 0x7fffffff
|
||||
#define SHT_LOUSER 0x80000000
|
||||
#define SHT_HIUSER 0xffffffff
|
||||
|
||||
/* sh_flags */
|
||||
#define SHF_WRITE 0x1
|
||||
#define SHF_ALLOC 0x2
|
||||
#define SHF_EXECINSTR 0x4
|
||||
#define SHF_RELA_LIVEPATCH 0x00100000
|
||||
#define SHF_RO_AFTER_INIT 0x00200000
|
||||
#define SHF_MASKPROC 0xf0000000
|
||||
|
||||
/* special section indexes */
|
||||
#define SHN_UNDEF 0
|
||||
#define SHN_LORESERVE 0xff00
|
||||
#define SHN_LOPROC 0xff00
|
||||
#define SHN_HIPROC 0xff1f
|
||||
#define SHN_LIVEPATCH 0xff20
|
||||
#define SHN_ABS 0xfff1
|
||||
#define SHN_COMMON 0xfff2
|
||||
#define SHN_HIRESERVE 0xffff
|
||||
|
||||
typedef struct elf32_shdr {
|
||||
Elf32_Word sh_name;
|
||||
Elf32_Word sh_type;
|
||||
Elf32_Word sh_flags;
|
||||
Elf32_Addr sh_addr;
|
||||
Elf32_Off sh_offset;
|
||||
Elf32_Word sh_size;
|
||||
Elf32_Word sh_link;
|
||||
Elf32_Word sh_info;
|
||||
Elf32_Word sh_addralign;
|
||||
Elf32_Word sh_entsize;
|
||||
} Elf32_Shdr;
|
||||
|
||||
typedef struct elf64_shdr {
|
||||
Elf64_Word sh_name; /* Section name, index in string tbl */
|
||||
Elf64_Word sh_type; /* Type of section */
|
||||
Elf64_Xword sh_flags; /* Miscellaneous section attributes */
|
||||
Elf64_Addr sh_addr; /* Section virtual addr at execution */
|
||||
Elf64_Off sh_offset; /* Section file offset */
|
||||
Elf64_Xword sh_size; /* Size of section in bytes */
|
||||
Elf64_Word sh_link; /* Index of another section */
|
||||
Elf64_Word sh_info; /* Additional section information */
|
||||
Elf64_Xword sh_addralign; /* Section alignment */
|
||||
Elf64_Xword sh_entsize; /* Entry size if section holds table */
|
||||
} Elf64_Shdr;
|
||||
|
||||
#define EI_MAG0 0 /* e_ident[] indexes */
|
||||
#define EI_MAG1 1
|
||||
#define EI_MAG2 2
|
||||
#define EI_MAG3 3
|
||||
#define EI_CLASS 4
|
||||
#define EI_DATA 5
|
||||
#define EI_VERSION 6
|
||||
#define EI_OSABI 7
|
||||
#define EI_PAD 8
|
||||
|
||||
#define ELFMAG0 0x7f /* EI_MAG */
|
||||
#define ELFMAG1 'E'
|
||||
#define ELFMAG2 'L'
|
||||
#define ELFMAG3 'F'
|
||||
#define ELFMAG "\177ELF"
|
||||
#define SELFMAG 4
|
||||
|
||||
#define ELFCLASSNONE 0 /* EI_CLASS */
|
||||
#define ELFCLASS32 1
|
||||
#define ELFCLASS64 2
|
||||
#define ELFCLASSNUM 3
|
||||
|
||||
#define ELFDATANONE 0 /* e_ident[EI_DATA] */
|
||||
#define ELFDATA2LSB 1
|
||||
#define ELFDATA2MSB 2
|
||||
|
||||
#define EV_NONE 0 /* e_version, EI_VERSION */
|
||||
#define EV_CURRENT 1
|
||||
#define EV_NUM 2
|
||||
|
||||
#define ELFOSABI_NONE 0
|
||||
#define ELFOSABI_LINUX 3
|
||||
|
||||
#ifndef ELF_OSABI
|
||||
#define ELF_OSABI ELFOSABI_NONE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Notes used in ET_CORE. Architectures export some of the arch register sets
|
||||
* using the corresponding note types via the PTRACE_GETREGSET and
|
||||
* PTRACE_SETREGSET requests.
|
||||
*/
|
||||
#define NT_PRSTATUS 1
|
||||
#define NT_PRFPREG 2
|
||||
#define NT_PRPSINFO 3
|
||||
#define NT_TASKSTRUCT 4
|
||||
#define NT_AUXV 6
|
||||
/*
|
||||
* Note to userspace developers: size of NT_SIGINFO note may increase
|
||||
* in the future to accomodate more fields, don't assume it is fixed!
|
||||
*/
|
||||
#define NT_SIGINFO 0x53494749
|
||||
#define NT_FILE 0x46494c45
|
||||
#define NT_PRXFPREG 0x46e62b7f /* copied from gdb5.1/include/elf/common.h */
|
||||
#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */
|
||||
#define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */
|
||||
#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */
|
||||
#define NT_PPC_TAR 0x103 /* Target Address Register */
|
||||
#define NT_PPC_PPR 0x104 /* Program Priority Register */
|
||||
#define NT_PPC_DSCR 0x105 /* Data Stream Control Register */
|
||||
#define NT_PPC_EBB 0x106 /* Event Based Branch Registers */
|
||||
#define NT_PPC_PMU 0x107 /* Performance Monitor Registers */
|
||||
#define NT_PPC_TM_CGPR 0x108 /* TM checkpointed GPR Registers */
|
||||
#define NT_PPC_TM_CFPR 0x109 /* TM checkpointed FPR Registers */
|
||||
#define NT_PPC_TM_CVMX 0x10a /* TM checkpointed VMX Registers */
|
||||
#define NT_PPC_TM_CVSX 0x10b /* TM checkpointed VSX Registers */
|
||||
#define NT_PPC_TM_SPR 0x10c /* TM Special Purpose Registers */
|
||||
#define NT_PPC_TM_CTAR 0x10d /* TM checkpointed Target Address Register */
|
||||
#define NT_PPC_TM_CPPR 0x10e /* TM checkpointed Program Priority Register */
|
||||
#define NT_PPC_TM_CDSCR 0x10f /* TM checkpointed Data Stream Control Register */
|
||||
#define NT_PPC_PKEY 0x110 /* Memory Protection Keys registers */
|
||||
#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */
|
||||
#define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */
|
||||
#define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */
|
||||
#define NT_S390_HIGH_GPRS 0x300 /* s390 upper register halves */
|
||||
#define NT_S390_TIMER 0x301 /* s390 timer register */
|
||||
#define NT_S390_TODCMP 0x302 /* s390 TOD clock comparator register */
|
||||
#define NT_S390_TODPREG 0x303 /* s390 TOD programmable register */
|
||||
#define NT_S390_CTRS 0x304 /* s390 control registers */
|
||||
#define NT_S390_PREFIX 0x305 /* s390 prefix register */
|
||||
#define NT_S390_LAST_BREAK 0x306 /* s390 breaking event address */
|
||||
#define NT_S390_SYSTEM_CALL 0x307 /* s390 system call restart data */
|
||||
#define NT_S390_TDB 0x308 /* s390 transaction diagnostic block */
|
||||
#define NT_S390_VXRS_LOW 0x309 /* s390 vector registers 0-15 upper half */
|
||||
#define NT_S390_VXRS_HIGH 0x30a /* s390 vector registers 16-31 */
|
||||
#define NT_S390_GS_CB 0x30b /* s390 guarded storage registers */
|
||||
#define NT_S390_GS_BC 0x30c /* s390 guarded storage broadcast control block */
|
||||
#define NT_S390_RI_CB 0x30d /* s390 runtime instrumentation */
|
||||
#define NT_ARM_VFP 0x400 /* ARM VFP/NEON registers */
|
||||
#define NT_ARM_TLS 0x401 /* ARM TLS register */
|
||||
#define NT_ARM_HW_BREAK 0x402 /* ARM hardware breakpoint registers */
|
||||
#define NT_ARM_HW_WATCH 0x403 /* ARM hardware watchpoint registers */
|
||||
#define NT_ARM_SYSTEM_CALL 0x404 /* ARM system call number */
|
||||
#define NT_ARM_SVE 0x405 /* ARM Scalable Vector Extension registers */
|
||||
#define NT_ARM_PAC_MASK 0x406 /* ARM pointer authentication code masks */
|
||||
#define NT_ARC_V2 0x600 /* ARCv2 accumulator/extra registers */
|
||||
#define NT_VMCOREDD 0x700 /* Vmcore Device Dump Note */
|
||||
#define NT_MIPS_DSP 0x800 /* MIPS DSP ASE registers */
|
||||
#define NT_MIPS_FP_MODE 0x801 /* MIPS floating-point mode */
|
||||
#define NT_MIPS_MSA 0x802 /* MIPS SIMD registers */
|
||||
|
||||
/* Note header in a PT_NOTE section */
|
||||
typedef struct elf32_note {
|
||||
Elf32_Word n_namesz; /* Name size */
|
||||
Elf32_Word n_descsz; /* Content size */
|
||||
Elf32_Word n_type; /* Content type */
|
||||
} Elf32_Nhdr;
|
||||
|
||||
/* Note header in a PT_NOTE section */
|
||||
typedef struct elf64_note {
|
||||
Elf64_Word n_namesz; /* Name size */
|
||||
Elf64_Word n_descsz; /* Content size */
|
||||
Elf64_Word n_type; /* Content type */
|
||||
} Elf64_Nhdr;
|
||||
|
||||
#endif /* _UAPI_LINUX_ELF_H */
|
||||
@@ -1,274 +0,0 @@
|
||||
/* multiboot.h - Multiboot header file. */
|
||||
/* Copyright (C) 1999,2003,2007,2008,2009,2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY
|
||||
* DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
* IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MULTIBOOT_HEADER
|
||||
#define MULTIBOOT_HEADER 1
|
||||
|
||||
/* How many bytes from the start of the file we search for the header. */
|
||||
#define MULTIBOOT_SEARCH 8192
|
||||
#define MULTIBOOT_HEADER_ALIGN 4
|
||||
|
||||
/* The magic field should contain this. */
|
||||
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
|
||||
|
||||
/* This should be in %eax. */
|
||||
#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
|
||||
|
||||
/* Alignment of multiboot modules. */
|
||||
#define MULTIBOOT_MOD_ALIGN 0x00001000
|
||||
|
||||
/* Alignment of the multiboot info structure. */
|
||||
#define MULTIBOOT_INFO_ALIGN 0x00000004
|
||||
|
||||
/* Flags set in the 'flags' member of the multiboot header. */
|
||||
|
||||
/* Align all boot modules on i386 page (4KB) boundaries. */
|
||||
#define MULTIBOOT_PAGE_ALIGN 0x00000001
|
||||
|
||||
/* Must pass memory information to OS. */
|
||||
#define MULTIBOOT_MEMORY_INFO 0x00000002
|
||||
|
||||
/* Must pass video information to OS. */
|
||||
#define MULTIBOOT_VIDEO_MODE 0x00000004
|
||||
|
||||
/* This flag indicates the use of the address fields in the header. */
|
||||
#define MULTIBOOT_AOUT_KLUDGE 0x00010000
|
||||
|
||||
/* Flags to be set in the 'flags' member of the multiboot info structure. */
|
||||
|
||||
/* is there basic lower/upper memory information? */
|
||||
#define MULTIBOOT_INFO_MEMORY 0x00000001
|
||||
/* is there a boot device set? */
|
||||
#define MULTIBOOT_INFO_BOOTDEV 0x00000002
|
||||
/* is the command-line defined? */
|
||||
#define MULTIBOOT_INFO_CMDLINE 0x00000004
|
||||
/* are there modules to do something with? */
|
||||
#define MULTIBOOT_INFO_MODS 0x00000008
|
||||
|
||||
/* These next two are mutually exclusive */
|
||||
|
||||
/* is there a symbol table loaded? */
|
||||
#define MULTIBOOT_INFO_AOUT_SYMS 0x00000010
|
||||
/* is there an ELF section header table? */
|
||||
#define MULTIBOOT_INFO_ELF_SHDR 0X00000020
|
||||
|
||||
/* is there a full memory map? */
|
||||
#define MULTIBOOT_INFO_MEM_MAP 0x00000040
|
||||
|
||||
/* Is there drive info? */
|
||||
#define MULTIBOOT_INFO_DRIVE_INFO 0x00000080
|
||||
|
||||
/* Is there a config table? */
|
||||
#define MULTIBOOT_INFO_CONFIG_TABLE 0x00000100
|
||||
|
||||
/* Is there a boot loader name? */
|
||||
#define MULTIBOOT_INFO_BOOT_LOADER_NAME 0x00000200
|
||||
|
||||
/* Is there a APM table? */
|
||||
#define MULTIBOOT_INFO_APM_TABLE 0x00000400
|
||||
|
||||
/* Is there video information? */
|
||||
#define MULTIBOOT_INFO_VBE_INFO 0x00000800
|
||||
#define MULTIBOOT_INFO_FRAMEBUFFER_INFO 0x00001000
|
||||
|
||||
#ifndef ASM_FILE
|
||||
|
||||
typedef unsigned char multiboot_uint8_t;
|
||||
typedef unsigned short multiboot_uint16_t;
|
||||
typedef unsigned int multiboot_uint32_t;
|
||||
typedef unsigned long long multiboot_uint64_t;
|
||||
|
||||
struct multiboot_header
|
||||
{
|
||||
/* Must be MULTIBOOT_MAGIC - see above. */
|
||||
multiboot_uint32_t magic;
|
||||
|
||||
/* Feature flags. */
|
||||
multiboot_uint32_t flags;
|
||||
|
||||
/* The above fields plus this one must equal 0 mod 2^32. */
|
||||
multiboot_uint32_t checksum;
|
||||
|
||||
/* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */
|
||||
multiboot_uint32_t header_addr;
|
||||
multiboot_uint32_t load_addr;
|
||||
multiboot_uint32_t load_end_addr;
|
||||
multiboot_uint32_t bss_end_addr;
|
||||
multiboot_uint32_t entry_addr;
|
||||
|
||||
/* These are only valid if MULTIBOOT_VIDEO_MODE is set. */
|
||||
multiboot_uint32_t mode_type;
|
||||
multiboot_uint32_t width;
|
||||
multiboot_uint32_t height;
|
||||
multiboot_uint32_t depth;
|
||||
};
|
||||
|
||||
/* The symbol table for a.out. */
|
||||
struct multiboot_aout_symbol_table
|
||||
{
|
||||
multiboot_uint32_t tabsize;
|
||||
multiboot_uint32_t strsize;
|
||||
multiboot_uint32_t addr;
|
||||
multiboot_uint32_t reserved;
|
||||
};
|
||||
typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t;
|
||||
|
||||
/* The section header table for ELF. */
|
||||
struct multiboot_elf_section_header_table
|
||||
{
|
||||
multiboot_uint32_t num;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t addr;
|
||||
multiboot_uint32_t shndx;
|
||||
};
|
||||
typedef struct multiboot_elf_section_header_table multiboot_elf_section_header_table_t;
|
||||
|
||||
struct multiboot_info
|
||||
{
|
||||
/* Multiboot info version number */
|
||||
multiboot_uint32_t flags;
|
||||
|
||||
/* Available memory from BIOS */
|
||||
multiboot_uint32_t mem_lower;
|
||||
multiboot_uint32_t mem_upper;
|
||||
|
||||
/* "root" partition */
|
||||
multiboot_uint32_t boot_device;
|
||||
|
||||
/* Kernel command line */
|
||||
multiboot_uint32_t cmdline;
|
||||
|
||||
/* Boot-Module list */
|
||||
multiboot_uint32_t mods_count;
|
||||
multiboot_uint32_t mods_addr;
|
||||
|
||||
union
|
||||
{
|
||||
multiboot_aout_symbol_table_t aout_sym;
|
||||
multiboot_elf_section_header_table_t elf_sec;
|
||||
} u;
|
||||
|
||||
/* Memory Mapping buffer */
|
||||
multiboot_uint32_t mmap_length;
|
||||
multiboot_uint32_t mmap_addr;
|
||||
|
||||
/* Drive Info buffer */
|
||||
multiboot_uint32_t drives_length;
|
||||
multiboot_uint32_t drives_addr;
|
||||
|
||||
/* ROM configuration table */
|
||||
multiboot_uint32_t config_table;
|
||||
|
||||
/* Boot Loader Name */
|
||||
multiboot_uint32_t boot_loader_name;
|
||||
|
||||
/* APM table */
|
||||
multiboot_uint32_t apm_table;
|
||||
|
||||
/* Video */
|
||||
multiboot_uint32_t vbe_control_info;
|
||||
multiboot_uint32_t vbe_mode_info;
|
||||
multiboot_uint16_t vbe_mode;
|
||||
multiboot_uint16_t vbe_interface_seg;
|
||||
multiboot_uint16_t vbe_interface_off;
|
||||
multiboot_uint16_t vbe_interface_len;
|
||||
|
||||
multiboot_uint64_t framebuffer_addr;
|
||||
multiboot_uint32_t framebuffer_pitch;
|
||||
multiboot_uint32_t framebuffer_width;
|
||||
multiboot_uint32_t framebuffer_height;
|
||||
multiboot_uint8_t framebuffer_bpp;
|
||||
#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
|
||||
#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1
|
||||
#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2
|
||||
multiboot_uint8_t framebuffer_type;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
multiboot_uint32_t framebuffer_palette_addr;
|
||||
multiboot_uint16_t framebuffer_palette_num_colors;
|
||||
};
|
||||
struct
|
||||
{
|
||||
multiboot_uint8_t framebuffer_red_field_position;
|
||||
multiboot_uint8_t framebuffer_red_mask_size;
|
||||
multiboot_uint8_t framebuffer_green_field_position;
|
||||
multiboot_uint8_t framebuffer_green_mask_size;
|
||||
multiboot_uint8_t framebuffer_blue_field_position;
|
||||
multiboot_uint8_t framebuffer_blue_mask_size;
|
||||
};
|
||||
};
|
||||
};
|
||||
typedef struct multiboot_info multiboot_info_t;
|
||||
|
||||
struct multiboot_color
|
||||
{
|
||||
multiboot_uint8_t red;
|
||||
multiboot_uint8_t green;
|
||||
multiboot_uint8_t blue;
|
||||
};
|
||||
|
||||
struct multiboot_mmap_entry
|
||||
{
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint64_t addr;
|
||||
multiboot_uint64_t len;
|
||||
#define MULTIBOOT_MEMORY_AVAILABLE 1
|
||||
#define MULTIBOOT_MEMORY_RESERVED 2
|
||||
#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3
|
||||
#define MULTIBOOT_MEMORY_NVS 4
|
||||
#define MULTIBOOT_MEMORY_BADRAM 5
|
||||
multiboot_uint32_t type;
|
||||
} __attribute__((packed));
|
||||
typedef struct multiboot_mmap_entry multiboot_memory_map_t;
|
||||
|
||||
struct multiboot_mod_list
|
||||
{
|
||||
/* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */
|
||||
multiboot_uint32_t mod_start;
|
||||
multiboot_uint32_t mod_end;
|
||||
|
||||
/* Module command line */
|
||||
multiboot_uint32_t cmdline;
|
||||
|
||||
/* padding to take it to 16 bytes (must be zero) */
|
||||
multiboot_uint32_t pad;
|
||||
};
|
||||
typedef struct multiboot_mod_list multiboot_module_t;
|
||||
|
||||
/* APM BIOS info. */
|
||||
struct multiboot_apm_info
|
||||
{
|
||||
multiboot_uint16_t version;
|
||||
multiboot_uint16_t cseg;
|
||||
multiboot_uint32_t offset;
|
||||
multiboot_uint16_t cseg_16;
|
||||
multiboot_uint16_t dseg;
|
||||
multiboot_uint16_t flags;
|
||||
multiboot_uint16_t cseg_len;
|
||||
multiboot_uint16_t cseg_16_len;
|
||||
multiboot_uint16_t dseg_len;
|
||||
};
|
||||
|
||||
#endif /* ! ASM_FILE */
|
||||
|
||||
#endif /* ! MULTIBOOT_HEADER */
|
||||
@@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// General utils
|
||||
size_t strlen(const char *s);
|
||||
char *strcpy(char *dst, const char *src);
|
||||
void *memset(void *blk, int v, size_t sz);
|
||||
void *memcpy(void *dst, const void *src, size_t sz);
|
||||
int strcmp(const char *a, const char *b);
|
||||
int strncmp(const char *a, const char *b, size_t lim);
|
||||
|
||||
// Debug utils
|
||||
void panic(const char *s);
|
||||
void puts(const char *s);
|
||||
void putx(uint64_t v);
|
||||
void putc(char c);
|
||||
@@ -1,7 +1,6 @@
|
||||
/* vim: set ft=cpp.doxygen : */
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include "arch/amd64/loader/data.h"
|
||||
|
||||
/// The place where the kernel pages are virtually mapped to
|
||||
#define KERNEL_VIRT_BASE 0xFFFFFF0000000000
|
||||
@@ -62,4 +61,4 @@ typedef mm_pml4_t mm_space_t;
|
||||
/// Kernel memory space
|
||||
extern mm_space_t mm_kernel;
|
||||
|
||||
void amd64_mm_init(struct amd64_loader_data *data);
|
||||
void amd64_mm_init(void);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "arch/amd64/loader/multiboot.h"
|
||||
#include "arch/amd64/multiboot2.h"
|
||||
#include "sys/types.h"
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -9,7 +9,8 @@ struct amd64_phys_stat {
|
||||
size_t limit;
|
||||
};
|
||||
|
||||
void amd64_phys_memory_map(const multiboot_memory_map_t *mmap, size_t length);
|
||||
void amd64_phys_memory_map(const struct multiboot_tag_mmap *mmap);
|
||||
//void amd64_phys_memory_map(const multiboot_memory_map_t *mmap, size_t length);
|
||||
|
||||
//void amd64_phys_free(uintptr_t page);
|
||||
//uintptr_t amd64_phys_alloc_page(void);
|
||||
|
||||
@@ -0,0 +1,417 @@
|
||||
/* multiboot2.h - Multiboot 2 header file. */
|
||||
/* Copyright (C) 1999,2003,2007,2008,2009,2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY
|
||||
* DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
* IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MULTIBOOT_HEADER
|
||||
#define MULTIBOOT_HEADER 1
|
||||
|
||||
/* How many bytes from the start of the file we search for the header. */
|
||||
#define MULTIBOOT_SEARCH 32768
|
||||
#define MULTIBOOT_HEADER_ALIGN 8
|
||||
|
||||
/* The magic field should contain this. */
|
||||
#define MULTIBOOT2_HEADER_MAGIC 0xe85250d6
|
||||
|
||||
/* This should be in %eax. */
|
||||
#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289
|
||||
|
||||
/* Alignment of multiboot modules. */
|
||||
#define MULTIBOOT_MOD_ALIGN 0x00001000
|
||||
|
||||
/* Alignment of the multiboot info structure. */
|
||||
#define MULTIBOOT_INFO_ALIGN 0x00000008
|
||||
|
||||
/* Flags set in the 'flags' member of the multiboot header. */
|
||||
|
||||
#define MULTIBOOT_TAG_ALIGN 8
|
||||
#define MULTIBOOT_TAG_TYPE_END 0
|
||||
#define MULTIBOOT_TAG_TYPE_CMDLINE 1
|
||||
#define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME 2
|
||||
#define MULTIBOOT_TAG_TYPE_MODULE 3
|
||||
#define MULTIBOOT_TAG_TYPE_BASIC_MEMINFO 4
|
||||
#define MULTIBOOT_TAG_TYPE_BOOTDEV 5
|
||||
#define MULTIBOOT_TAG_TYPE_MMAP 6
|
||||
#define MULTIBOOT_TAG_TYPE_VBE 7
|
||||
#define MULTIBOOT_TAG_TYPE_FRAMEBUFFER 8
|
||||
#define MULTIBOOT_TAG_TYPE_ELF_SECTIONS 9
|
||||
#define MULTIBOOT_TAG_TYPE_APM 10
|
||||
#define MULTIBOOT_TAG_TYPE_EFI32 11
|
||||
#define MULTIBOOT_TAG_TYPE_EFI64 12
|
||||
#define MULTIBOOT_TAG_TYPE_SMBIOS 13
|
||||
#define MULTIBOOT_TAG_TYPE_ACPI_OLD 14
|
||||
#define MULTIBOOT_TAG_TYPE_ACPI_NEW 15
|
||||
#define MULTIBOOT_TAG_TYPE_NETWORK 16
|
||||
#define MULTIBOOT_TAG_TYPE_EFI_MMAP 17
|
||||
#define MULTIBOOT_TAG_TYPE_EFI_BS 18
|
||||
#define MULTIBOOT_TAG_TYPE_EFI32_IH 19
|
||||
#define MULTIBOOT_TAG_TYPE_EFI64_IH 20
|
||||
#define MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR 21
|
||||
|
||||
#define MULTIBOOT_HEADER_TAG_END 0
|
||||
#define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST 1
|
||||
#define MULTIBOOT_HEADER_TAG_ADDRESS 2
|
||||
#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS 3
|
||||
#define MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS 4
|
||||
#define MULTIBOOT_HEADER_TAG_FRAMEBUFFER 5
|
||||
#define MULTIBOOT_HEADER_TAG_MODULE_ALIGN 6
|
||||
#define MULTIBOOT_HEADER_TAG_EFI_BS 7
|
||||
#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI32 8
|
||||
#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 9
|
||||
#define MULTIBOOT_HEADER_TAG_RELOCATABLE 10
|
||||
|
||||
#define MULTIBOOT_ARCHITECTURE_I386 0
|
||||
#define MULTIBOOT_ARCHITECTURE_MIPS32 4
|
||||
#define MULTIBOOT_HEADER_TAG_OPTIONAL 1
|
||||
|
||||
#define MULTIBOOT_LOAD_PREFERENCE_NONE 0
|
||||
#define MULTIBOOT_LOAD_PREFERENCE_LOW 1
|
||||
#define MULTIBOOT_LOAD_PREFERENCE_HIGH 2
|
||||
|
||||
#define MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED 1
|
||||
#define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2
|
||||
|
||||
#ifndef ASM_FILE
|
||||
|
||||
typedef unsigned char multiboot_uint8_t;
|
||||
typedef unsigned short multiboot_uint16_t;
|
||||
typedef unsigned int multiboot_uint32_t;
|
||||
typedef unsigned long long multiboot_uint64_t;
|
||||
|
||||
struct multiboot_header
|
||||
{
|
||||
/* Must be MULTIBOOT_MAGIC - see above. */
|
||||
multiboot_uint32_t magic;
|
||||
|
||||
/* ISA */
|
||||
multiboot_uint32_t architecture;
|
||||
|
||||
/* Total header length. */
|
||||
multiboot_uint32_t header_length;
|
||||
|
||||
/* The above fields plus this one must equal 0 mod 2^32. */
|
||||
multiboot_uint32_t checksum;
|
||||
};
|
||||
|
||||
struct multiboot_header_tag
|
||||
{
|
||||
multiboot_uint16_t type;
|
||||
multiboot_uint16_t flags;
|
||||
multiboot_uint32_t size;
|
||||
};
|
||||
|
||||
struct multiboot_header_tag_information_request
|
||||
{
|
||||
multiboot_uint16_t type;
|
||||
multiboot_uint16_t flags;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t requests[0];
|
||||
};
|
||||
|
||||
struct multiboot_header_tag_address
|
||||
{
|
||||
multiboot_uint16_t type;
|
||||
multiboot_uint16_t flags;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t header_addr;
|
||||
multiboot_uint32_t load_addr;
|
||||
multiboot_uint32_t load_end_addr;
|
||||
multiboot_uint32_t bss_end_addr;
|
||||
};
|
||||
|
||||
struct multiboot_header_tag_entry_address
|
||||
{
|
||||
multiboot_uint16_t type;
|
||||
multiboot_uint16_t flags;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t entry_addr;
|
||||
};
|
||||
|
||||
struct multiboot_header_tag_console_flags
|
||||
{
|
||||
multiboot_uint16_t type;
|
||||
multiboot_uint16_t flags;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t console_flags;
|
||||
};
|
||||
|
||||
struct multiboot_header_tag_framebuffer
|
||||
{
|
||||
multiboot_uint16_t type;
|
||||
multiboot_uint16_t flags;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t width;
|
||||
multiboot_uint32_t height;
|
||||
multiboot_uint32_t depth;
|
||||
};
|
||||
|
||||
struct multiboot_header_tag_module_align
|
||||
{
|
||||
multiboot_uint16_t type;
|
||||
multiboot_uint16_t flags;
|
||||
multiboot_uint32_t size;
|
||||
};
|
||||
|
||||
struct multiboot_header_tag_relocatable
|
||||
{
|
||||
multiboot_uint16_t type;
|
||||
multiboot_uint16_t flags;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t min_addr;
|
||||
multiboot_uint32_t max_addr;
|
||||
multiboot_uint32_t align;
|
||||
multiboot_uint32_t preference;
|
||||
};
|
||||
|
||||
struct multiboot_color
|
||||
{
|
||||
multiboot_uint8_t red;
|
||||
multiboot_uint8_t green;
|
||||
multiboot_uint8_t blue;
|
||||
};
|
||||
|
||||
struct multiboot_mmap_entry
|
||||
{
|
||||
multiboot_uint64_t addr;
|
||||
multiboot_uint64_t len;
|
||||
#define MULTIBOOT_MEMORY_AVAILABLE 1
|
||||
#define MULTIBOOT_MEMORY_RESERVED 2
|
||||
#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3
|
||||
#define MULTIBOOT_MEMORY_NVS 4
|
||||
#define MULTIBOOT_MEMORY_BADRAM 5
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t zero;
|
||||
};
|
||||
typedef struct multiboot_mmap_entry multiboot_memory_map_t;
|
||||
|
||||
struct multiboot_tag
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
};
|
||||
|
||||
struct multiboot_tag_string
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
char string[0];
|
||||
};
|
||||
|
||||
struct multiboot_tag_module
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t mod_start;
|
||||
multiboot_uint32_t mod_end;
|
||||
char cmdline[0];
|
||||
};
|
||||
|
||||
struct multiboot_tag_basic_meminfo
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t mem_lower;
|
||||
multiboot_uint32_t mem_upper;
|
||||
};
|
||||
|
||||
struct multiboot_tag_bootdev
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t biosdev;
|
||||
multiboot_uint32_t slice;
|
||||
multiboot_uint32_t part;
|
||||
};
|
||||
|
||||
struct multiboot_tag_mmap
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t entry_size;
|
||||
multiboot_uint32_t entry_version;
|
||||
struct multiboot_mmap_entry entries[0];
|
||||
};
|
||||
|
||||
struct multiboot_vbe_info_block
|
||||
{
|
||||
multiboot_uint8_t external_specification[512];
|
||||
};
|
||||
|
||||
struct multiboot_vbe_mode_info_block
|
||||
{
|
||||
multiboot_uint8_t external_specification[256];
|
||||
};
|
||||
|
||||
struct multiboot_tag_vbe
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
|
||||
multiboot_uint16_t vbe_mode;
|
||||
multiboot_uint16_t vbe_interface_seg;
|
||||
multiboot_uint16_t vbe_interface_off;
|
||||
multiboot_uint16_t vbe_interface_len;
|
||||
|
||||
struct multiboot_vbe_info_block vbe_control_info;
|
||||
struct multiboot_vbe_mode_info_block vbe_mode_info;
|
||||
};
|
||||
|
||||
struct multiboot_tag_framebuffer_common
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
|
||||
multiboot_uint64_t framebuffer_addr;
|
||||
multiboot_uint32_t framebuffer_pitch;
|
||||
multiboot_uint32_t framebuffer_width;
|
||||
multiboot_uint32_t framebuffer_height;
|
||||
multiboot_uint8_t framebuffer_bpp;
|
||||
#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
|
||||
#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1
|
||||
#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2
|
||||
multiboot_uint8_t framebuffer_type;
|
||||
multiboot_uint16_t reserved;
|
||||
};
|
||||
|
||||
struct multiboot_tag_framebuffer
|
||||
{
|
||||
struct multiboot_tag_framebuffer_common common;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
multiboot_uint16_t framebuffer_palette_num_colors;
|
||||
struct multiboot_color framebuffer_palette[0];
|
||||
};
|
||||
struct
|
||||
{
|
||||
multiboot_uint8_t framebuffer_red_field_position;
|
||||
multiboot_uint8_t framebuffer_red_mask_size;
|
||||
multiboot_uint8_t framebuffer_green_field_position;
|
||||
multiboot_uint8_t framebuffer_green_mask_size;
|
||||
multiboot_uint8_t framebuffer_blue_field_position;
|
||||
multiboot_uint8_t framebuffer_blue_mask_size;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
struct multiboot_tag_elf_sections
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t num;
|
||||
multiboot_uint32_t entsize;
|
||||
multiboot_uint32_t shndx;
|
||||
char sections[0];
|
||||
};
|
||||
|
||||
struct multiboot_tag_apm
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint16_t version;
|
||||
multiboot_uint16_t cseg;
|
||||
multiboot_uint32_t offset;
|
||||
multiboot_uint16_t cseg_16;
|
||||
multiboot_uint16_t dseg;
|
||||
multiboot_uint16_t flags;
|
||||
multiboot_uint16_t cseg_len;
|
||||
multiboot_uint16_t cseg_16_len;
|
||||
multiboot_uint16_t dseg_len;
|
||||
};
|
||||
|
||||
struct multiboot_tag_efi32
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t pointer;
|
||||
};
|
||||
|
||||
struct multiboot_tag_efi64
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint64_t pointer;
|
||||
};
|
||||
|
||||
struct multiboot_tag_smbios
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint8_t major;
|
||||
multiboot_uint8_t minor;
|
||||
multiboot_uint8_t reserved[6];
|
||||
multiboot_uint8_t tables[0];
|
||||
};
|
||||
|
||||
struct multiboot_tag_old_acpi
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint8_t rsdp[0];
|
||||
};
|
||||
|
||||
struct multiboot_tag_new_acpi
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint8_t rsdp[0];
|
||||
};
|
||||
|
||||
struct multiboot_tag_network
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint8_t dhcpack[0];
|
||||
};
|
||||
|
||||
struct multiboot_tag_efi_mmap
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t descr_size;
|
||||
multiboot_uint32_t descr_vers;
|
||||
multiboot_uint8_t efi_mmap[0];
|
||||
};
|
||||
|
||||
struct multiboot_tag_efi32_ih
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t pointer;
|
||||
};
|
||||
|
||||
struct multiboot_tag_efi64_ih
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint64_t pointer;
|
||||
};
|
||||
|
||||
struct multiboot_tag_load_base_addr
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t load_base_addr;
|
||||
};
|
||||
|
||||
#endif /* ! ASM_FILE */
|
||||
|
||||
#endif /* ! MULTIBOOT_HEADER */
|
||||
@@ -1,11 +1,8 @@
|
||||
#pragma once
|
||||
#if defined(ARCH_AMD64)
|
||||
// For KERNEL_CMDLINE_MAX
|
||||
#include "arch/amd64/loader/data.h"
|
||||
#endif
|
||||
|
||||
#include "sys/types.h"
|
||||
|
||||
#define KERNEL_CMDLINE_MAX 256
|
||||
|
||||
enum {
|
||||
CFG_ROOT = 1,
|
||||
CFG_INIT,
|
||||
|
||||
Reference in New Issue
Block a user