switched to 16bit mode, but int 10h hangs
[efitest3] / efitest.asm
index 26d29d1..ae804dd 100644 (file)
@@ -1,8 +1,36 @@
 ; vi:ft=nasm:
        bits 64
-       org 100000h
+       org 1000h
+
+BOOT_SERVICES          equ 96
+BOOT_GET_MEMORY_MAP    equ 56
+BOOT_EXIT_BOOT_SERVICES        equ 232
 
 start:
+       mov [efihandle], rcx
+       mov [systab], rdx
+
+       ; retrieve memory map
+       ; args: RCX, RDX, R8, and R9.
+       lea rcx, [mmap_size]
+       lea rdx, [mmapbuf]
+       lea r8, [mmap_key]
+       lea r9, [mmap_descsz]
+       lea rax, [mmap_descver]
+       push rax
+       sub rsp, 32
+       mov rax, [systab]
+       mov rbx, [rax + BOOT_SERVICES]
+       call [rbx + BOOT_GET_MEMORY_MAP]
+       add rsp, 40
+       ; exit boot services
+       mov rcx, [efihandle]
+       mov rdx, [mmap_key]
+       mov rax, [systab]
+       mov rbx, [rax + BOOT_SERVICES]
+       call [rbx + BOOT_EXIT_BOOT_SERVICES]
+
+       ; move code to absolute 1000h
        call get_rip
 .after_call:
        sub rax, .after_call - start
@@ -72,10 +100,23 @@ setup_serial:
        out dx, al
        ret
 
+
+       align 8
+efihandle dq 0
+systab dq 0
+; memory map data
+mmap_size dq 4096
+mmap_key dq 0
+mmap_descsz dq 0
+mmap_descver dq 0
+
+       align 4096
+mmapbuf: times 4096 db 0
+
 str_hello db 'hello!',13,10,0
 
        align 4
-gdtlim dw 23
+gdtlim dw 31
 gdtbase        dq gdt
 
        align 8
@@ -87,7 +128,9 @@ gdt: ; 0: null segment
        ; 2: data - base:0, lim:4g, G:4k, 32bit, avl, pres|app, dpl:0, type:data/rw
        dd 0x0000ffff
        dd 0x00cf9200
-
+       ; 3: code16
+       dd 0x0000ffff
+       dd 0x00009a00
 
        bits 32
 start32:
@@ -110,8 +153,8 @@ start32:
        and eax, 0fffffeffh
        wrmsr
 
-       mov esi, str_hello
-       call ser_putstr
+       ; load 16bit code segment and jump to 16bit code
+       jmp 0x18:start16
 
 .hang: hlt
        jmp .hang
@@ -139,4 +182,45 @@ ser_putstr:
 .done: ret
 
 
+       align 4
+       ; real mode IDTR pseudo-descriptor pointing to the IVT at addr 0
+       dw 0
+rmidt: dw 3ffh
+       dd 0
+
+       bits 16
+start16:
+       ; disable protection
+       mov eax, cr0
+       and eax, 0fffffffeh
+       mov cr0, eax
+       ; load cs <- 0
+       jmp 0:.loadcs0
+.loadcs0:
+       ; zero data segments
+       xor ax, ax
+       mov ds, ax
+       mov es, ax
+       mov fs, ax
+       mov gs, ax
+       ; move stack to the top of 640k
+       mov ax, 9000h
+       mov ss, ax
+       xor sp, sp
+
+       ; run 16bit video bios test
+       mov ax, 13h
+       ;int 10h
+
+       mov ax, 0a000h
+       mov es, ax
+       xor di, di
+       mov cx, 32000
+       mov ax, 6767h
+       rep stosw
+
+.hang: hlt
+       jmp .hang
+
+       align 4
 end: