diff options
author | Johannes Stoelp <johannes.stoelp@gmail.com> | 2024-12-23 22:51:52 +0100 |
---|---|---|
committer | Johannes Stoelp <johannes.stoelp@gmail.com> | 2024-12-25 21:25:16 +0100 |
commit | 14845124cf5d4fb42a04cb1262b32bd3d00f45f8 (patch) | |
tree | 13162d26afeb49a9c9b8d9d31049066c0f4b2998 /x86-bare-metal/mbr-palette/mbr.S | |
parent | 42b6f9d23ab0f94744a90edb6fd74450f589ca14 (diff) | |
download | zig-playground-14845124cf5d4fb42a04cb1262b32bd3d00f45f8.tar.gz zig-playground-14845124cf5d4fb42a04cb1262b32bd3d00f45f8.zip |
mbr: rm->pm, then jump into zig
Diffstat (limited to 'x86-bare-metal/mbr-palette/mbr.S')
-rw-r--r-- | x86-bare-metal/mbr-palette/mbr.S | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/x86-bare-metal/mbr-palette/mbr.S b/x86-bare-metal/mbr-palette/mbr.S new file mode 100644 index 0000000..858f3f8 --- /dev/null +++ b/x86-bare-metal/mbr-palette/mbr.S @@ -0,0 +1,89 @@ +// -- BOOT TEXT SECTION --------------------------------------------------------- + +.code16 +.intel_syntax noprefix + +.section .boot, "ax", @progbits + // Disable interrupts. + cli + + // Clear segment selectors. + xor ax, ax + mov ds, ax + mov es, ax + mov ss, ax + mov fs, ax + mov gs, ax + + // Set cs to 0x0000, as some BIOSes load the MBR to either 07c0:0000 or 0000:7c000. + jmp 0x0000:entry_rm16 + +entry_rm16: + // Set video mode 13h, see [1]. + // * 320x200 graphic mode + // * 256 colors (8bit per pixel) + // * 0xA0000 screen address + // + // [1] http://www.ctyme.com/intr/rb-0069.htm + // [2] https://en.wikipedia.org/wiki/Mode_13h (shows color palette) + mov ax, 0x13 + int 0x10 + + // Set blue screen and halt if setting video mode failed. + jnc 2f + mov ah, 0xb + mov bx, 1 + int 0x10 +1: + hlt + jmp 1b +2: + + // Enable A20 address line. + in al, 0x92 + or al, 2 + out 0x92, al + + // Load GDT descriptor. + lgdt [gdt_desc] + + // Enable protected mode (set CR0.PE bit). + mov eax, cr0 + or eax, (1 << 0) + mov cr0, eax + + // Far jump which loads segment selector (0x0008) into cs. + // 0x0008 -> RPL=0, TI=0(GDT), I=1 + jmp 0x0008:entry_pm32 + +.code32 +entry_pm32: + // Select data segment selector (0x0010) for ds. + mov ax, gdt_data - gdt + mov ds, ax + + // Initialize stack pointer. + // Real Mode memory (https://wiki.osdev.org/Memory_Map_(x86) + // 0x00000500 - 0x00007BFF | 29.75 KiB | conventional memory + mov esp, 0x7c00 + + // Enter zmbr.zig:kmain. + // Should not return, but for safety we emit a call rather than a jmp. + call kmain + +1: + hlt + jmp 1b + +// -- RODATA SECTION ------------------------------------------------------------ + +.section .rodata, "a", @progbits +.balign 8 +gdt: + .8byte 0x0000000000000000 // 0x00 | null descriptor + .8byte 0x00cf9a000000ffff // 0x08 | 32 bit, code (rx), present, dpl=0, g=4K, base=0, limit=fffff +gdt_data: + .8byte 0x00cf92000000ffff // 0x10 | 32 bit, data (rw), present, dpl=0, g=4K, base=0, limit=fffff +gdt_desc: + .2byte (. - gdt - 1) // size + .4byte gdt // address |