[BITS 16] [ORG 0] START: ;; initialize segments mov ax, BOOT1SEG mov ds, ax mov es, ax mov ss, ax ;; make sure we are running on a 386+ ;; while we're still in real mode, detect system hardware via BIOS call PROBE_VIDEO call GET_EQUIPMENT_LIST call GET_MEMORY_SIZE call GET_TIME ;; switch the processor into protected mode, keep ints disabled cli lidt [IDT_Pointer] lgdt [GDT_Pointer] call ENABLE_A20 mov ax, 0x01 lmsw ax ;; Jump to 32 bit code, this completes the transition to protected mode db 0x66 ; operand size override prefix db 0xea ; jmp opcode dd (BOOT1SEG<<4) + setup_32 ; want to jump here dw (1<<3) ; ...in the kernel code segment [BITS 32] setup_32: ;; set up data segment registers mov ax, (2<<3) mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax ;; create an initial stack mov esp, KERN_STACK + 4096 mov ebp, esp ;; create a stack frame, pass ptr to hardware block as param mov eax, (BOOT1SEG<<4)+BIOS_HARDWARE_BLOCK push eax push (BOOT1SEG<<4)+.HANG jmp (1<<3):0x00010000 ; entry point of kernel .HANG: nop jmp .HANG ; Setup data ; ---------------------------------------------------------------------- BIOS_HARDWARE_BLOCK: bDisplayType db 0x00 bFontSize db 0x00 wEquipmentBitvector dw 0x0000 wMemorySize dw 0x0000 wSystemClock dw 0x0000 NUM_GDT_ENTRIES equ 3 ; number of entries in GDT GDT_ENTRY_SZ equ 8 ; size of a single GDT entry align 8, db 0 GDT: ; Descriptor 0 is not used dw 0 dw 0 dw 0 dw 0 ; Descriptor 1: kernel code segment dw 0xFFFF ; bytes 0 and 1 of segment size dw 0x0000 ; bytes 0 and 1 of segment base address db 0x00 ; byte 2 of segment base address db 0x9A ; present, DPL=0, non-system, code, non-conforming, ; readable, not accessed db 0xCF ; granularity=page, 32 bit code, upper nibble of size db 0x00 ; byte 3 of segment base address ; Descriptor 2: kernel data and stack segment ; NOTE: what Intel calls an "expand-up" segment ; actually means that the stack will grow DOWN, ; towards lower memory. So, we can use this descriptor ; for both data and stack references. dw 0xFFFF ; bytes 0 and 1 of segment size dw 0x0000 ; bytes 0 and 1 of segment base address db 0x00 ; byte 2 of segment base address db 0x92 ; present, DPL=0, non-system, data, expand-up, ; writable, not accessed db 0xCF ; granularity=page, big, upper nibble of size db 0x00 ; byte 3 of segment base address GDT_Pointer: dw NUM_GDT_ENTRIES*GDT_ENTRY_SZ ; limit dd (BOOT1SEG<<4) + GDT ; base address IDT_Pointer: dw 0 dd 00 %include "defs.asm" %include "hardware.asm" %include "video.asm"