diff options
author | Aqua-sama <aqua@iserlohn-fortress.net> | 2021-02-03 23:39:03 +0200 |
---|---|---|
committer | Aqua-sama <aqua@iserlohn-fortress.net> | 2021-02-03 23:39:43 +0200 |
commit | 039df4c04d83fc26ca60d4f870d2e58d381818ad (patch) | |
tree | 0896053cffebfe97ac98c98386d62ef7f2e980b1 /boot.s | |
parent | Update readme with required packages (diff) | |
download | kernel.cpp-039df4c04d83fc26ca60d4f870d2e58d381818ad.tar.xz |
Rewrite boot.s to use clang instead of nasm
Diffstat (limited to 'boot.s')
-rw-r--r-- | boot.s | 93 |
1 files changed, 93 insertions, 0 deletions
@@ -0,0 +1,93 @@ +/* + Declare a multiboot header that marks the program as a kernel. + https://www.gnu.org/software/grub/manual/multiboot2/html_node/index.html + + The Multiboot2 header must be contained completely within the first + 32kB of the OS image, and must be 64-bit (8 byte) aligned. +*/ +.set MULTIBOOT_HEADER_MAGIC, 0xe85250d6 # multiboot2 magic number +.set MULTIBOOT_ARCHITECTURE, 0 # protected mode i386 +.set MULTIBOOT_HEADER_TAG_END, 0 + +.section .multiboot +.align 8 +header_start: + .int MULTIBOOT_HEADER_MAGIC + .int MULTIBOOT_ARCHITECTURE + .int header_end - header_start + .int -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE + (header_end - header_start)) + + # TODO tags go here + + .short MULTIBOOT_HEADER_TAG_END + .short 0 + .int 8 +header_end: + +/* + The stack on x86 must be 16-byte aligned according to the System V ABI + standard and de-facto extensions. The compiler will assume the stack is + properly aligned and failure to align the stack will result in undefined + behavior. +*/ +.section .stack, "aw", @nobits +.align 16 +stack_bottom: + .skip 16 * 1024 +stack_top: + +/* + The linker script specifies _start as the entry point to the kernel and the + bootloader will jump to this position once the kernel has been loaded. +*/ +.section .text +.global _start +.type _start, @function +_start: + mov $stack_top, %esp # point the stack pointer to the stack + + /* + This is a good place to initialize crucial processor state before the + high-level kernel is entered. It's best to minimize the early + environment where crucial features are offline. Note that the + processor is not fully initialized yet: Features such as floating + point instructions and instruction set extensions are not initialized + yet. The GDT should be loaded here. Paging should be enabled here. + C++ features such as global constructors and exceptions will require + runtime support to work as well. + */ + + pushl %ebx # push the pointer to the multiboot structure + pushl %eax # push the multiboot magic value + + /* + Enter the high-level kernel. The ABI requires the stack is 16-byte + aligned at the time of the call instruction (which afterwards pushes + the return pointer of size 4 bytes). The stack was originally 16-byte + aligned above and we've pushed a multiple of 16 bytes to the + stack since (pushed 0 bytes so far), so the alignment has thus been + preserved and the call is well defined. + */ + call kernel_main + + /* + If the system has nothing more to do, put the computer into an + infinite loop. To do that: + 1) Disable interrupts with cli (clear interrupt enable in eflags). + They are already disabled by the bootloader, so this is not needed. + Mind that you might later enable interrupts and return from + kernel_main (which is sort of nonsensical to do). + 2) Wait for the next interrupt to arrive with hlt (halt instruction). + Since they are disabled, this will lock up the computer. + 3) Jump to the hlt instruction if it ever wakes up due to a + non-maskable interrupt occurring or due to system management mode. + */ + cli +hang: hlt + jmp hang + +/* +Set the size of the _start symbol to the current location '.' minus its start. +This is useful when debugging or when you implement call tracing. +*/ +.size _start, . - _start |