Add possibility to pick separate entry point to stivale

This commit is contained in:
mintsuki 2020-05-30 15:44:14 +02:00
parent e427ab4b64
commit 6540239006
5 changed files with 24 additions and 5 deletions

View File

@ -32,7 +32,9 @@ The kernel MUST NOT request to load itself at an address lower than `0x100000`
### 64-bit kernel
`rip` will be the entry point as defined in the ELF file.
`rip` will be the entry point as defined in the ELF file, unless the `entry_point`
field in the stivale header is set to a non-0 value, in which case, it is set to
the value of `entry_point`.
At entry, the bootloader will have setup paging such that there is a 4GiB identity
mapped block of memory at `0x0000000000000000`, a 2GiB mapped area of memory
@ -41,6 +43,10 @@ to `0xffffffff80000000` virtual. This area is for the higher half kernels.
Further more, a 4GiB area of memory from `0x0000000000000000` physical to
`0x0000000100000000` physical to `0xffff800000000000` virtual is mapped.
If the kernel is dynamic and not statically linked, the bootloader will relocate it.
Furthermore if bit 2 of the flags field in the stivale header is set, the bootloader
will perform kernel address space layout randomisation (KASLR).
The kernel should NOT modify the bootloader page tables, and it should only use them
to bootstrap its own virtual memory manager and its own page tables.
@ -67,7 +73,9 @@ The A20 gate is enabled.
### 32-bit kernel
`eip` will be the entry point as defined in the ELF file.
`eip` will be the entry point as defined in the ELF file, unless the `entry_point`
field in the stivale header is set to a non-0 value, in which case, it is set to
the value of `entry_point`.
At entry all segment registers are loaded as 32 bit code/data segments.
All segment bases are `0x00000000` and all limits are `0xffffffff`.
@ -112,6 +120,8 @@ struct stivale_header {
uint16_t framebuffer_height; // is requested. If all values are set to 0
uint16_t framebuffer_bpp; // then the bootloader will pick the best possible
// video mode automatically (recommended).
uint64_t entry_point; // If not 0, this field will be jumped to at entry
// instead of the ELF entry point.
} __attribute__((packed));
```

Binary file not shown.

View File

@ -216,6 +216,8 @@ int elf64_load_section(struct file_handle *fd, void *buffer, const char *name, s
if (!strcmp(&names[section.sh_name], name)) {
if (section.sh_size > limit)
return 3;
if (section.sh_size < limit)
return 4;
fread(fd, buffer, section.sh_offset, section.sh_size);
return elf64_apply_relocations(fd, &hdr, buffer, section.sh_addr, section.sh_size, slide);
}
@ -258,6 +260,8 @@ int elf32_load_section(struct file_handle *fd, void *buffer, const char *name, s
if (!strcmp(&names[section.sh_name], name)) {
if (section.sh_size > limit)
return 3;
if (section.sh_size < limit)
return 4;
fread(fd, buffer, section.sh_offset, section.sh_size);
return 0;
}

View File

@ -16,12 +16,11 @@
struct stivale_header {
uint64_t stack;
// Flags
// bit 0 0 = text mode, 1 = graphics mode
uint16_t flags;
uint16_t framebuffer_width;
uint16_t framebuffer_height;
uint16_t framebuffer_bpp;
uint64_t entry_point;
} __attribute__((packed));
struct stivale_module {
@ -134,6 +133,8 @@ void stivale_load(char *cmdline, int boot_drive) {
panic("stivale: Section .stivalehdr not found.");
case 3:
panic("stivale: Section .stivalehdr exceeds the size of the struct.");
case 4:
panic("stivale: Section .stivalehdr is smaller than size of the struct.");
}
print("stivale: Requested stack at %X\n", stivale_hdr.stack);
@ -150,6 +151,9 @@ void stivale_load(char *cmdline, int boot_drive) {
break;
}
if (stivale_hdr.entry_point != 0)
entry_point = stivale_hdr.entry_point;
print("stivale: Kernel slide: %X\n", slide);
print("stivale: Top used address in ELF: %X\n", top_used_addr);

View File

@ -9,6 +9,7 @@ stivale_header:
dw 0 ; fb_width
dw 0 ; fb_height
dw 0 ; fb_bpp
dq 0
section .bss
@ -29,4 +30,4 @@ _start:
mov [rdx], rax
mov [rdx+8], rbx
mov [rdx+16], rcx
jmp $
jmp $