;start.s ;Entrypoint for kernel, hello world! bits 32 ;Some symbols we'll need from other files... extern kern_main extern gdtr ;This will be our entrypoint function name - gotta initialize it now as global so the linker knows later. global start ; Set up for C code. Practically the only requirement for C-generated assembly to work properly is alignment and the presence of a stack. section .bss align=16 stack_bottom: resb 4096 ; 4096 bytes (4kb) large stack. by skipping some amount of data (and eventually filling it with zeroes?), we've essentially just reserved space for our stack. ;Remember, stack grows DOWNWARD! So the last thing in the section -> the highest memory address -> the very first thing on the stack! ;Therefore, we put a label here to represent the top of our stack for later. stack_top: ;We're gonna throw the TSS here too. tss: resb 104 ;Actual code. Entry point goes here! section .text ;Here it is! start: ;We made a GDT! Let's use it! lgdt [gdtr] ;Now we start by setting the code segment (CS) with a far jump... jmp 0x08:segment_be_gone segment_be_gone: ;Now we go ahead and dump our kernel mode data segment (0x10) into the rest of our segments. ;Also preserving eax because it has the bootloader's multiboot magic in it and I want to check it in main. mov cx, 0x10 mov ds, cx mov es, cx mov ss, cx mov fs, cx mov gs, cx ;Lets set up the stack. Stack grows downward on x86. We did the work earlier of defining where the top of the stack is, so just tell esp. mov esp, stack_top ;set the stack pointer push ebx push eax ;To C-land! call kern_main ;You should never get here, but in case you do, we will just hang. hang: cli ;Interrupts: off hlt ;Halt! jmp hang ;just in case...