org 0x0 [bits 16] entry: ; mov al, 0x01 ; Say where we are. ; out 0x80, al mov ax, 0xA800 mov ds, ax ; Take us out of flat unreal mode, and mov es, ax ; put us in true real mode. mov fs, ax mov gs, ax mov ss, ax jmp 0xA800:entry2 ; Long jump to a correct cs. entry2: ; mov al, 0x02 ; out 0x80, al lgdt [gdtr] ; Set up a new GDT. mov eax, 0x1 mov cr0, eax ; ... and enter pmode! mov al, 0x03 ; Say we got here. out 0x80, al jmp long 0x10:(continue+0xA8000) ; Now longjmp into the new code. [bits 32] continue: ; mov al, 0x04 ; Now we're in protected mode. ; out 0x80, al mov ax, 0x08 ; Set up segment selectors. mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax mov esp, 0x1fffffff ; mov al, 0x05 ; out 0x80, al mov al, [(cstat + 0xA8000)] add al, 1 out 0x80, al mov [(cstat + 0xA8000)], al mov eax, 0x11223344 mov dword [(status + 0xA8000)], eax mov dx, 0xCF8 ; save off the old config value in dword eax, dx mov [esp-4], eax mov eax, 0x80000070 ; load in smramc out dx, eax mov dx, 0xCFC in byte al, dx mov [esp-5], al and al, 0xF3 ; Allow graphics access or al, 0x08 out dx, al xor eax, eax mov dx, 0x3D4 in byte al, dx mov [esp-6], al ; save off the old VGA command mov al, 0xC out dx, al inc dx in al, dx mov ah, al dec dx mov al, 0xD out dx, al inc dx in al, dx shl eax, 1 add eax, 0xB8000 ; yay mov byte [eax+0], '1' mov byte [eax+1], 0xA0 mov byte [eax+2], '5' mov byte [eax+3], 0xA0 mov byte [eax+4], '-' mov byte [eax+5], 0xA0 mov byte [eax+6], '4' mov byte [eax+7], 0xA0 mov byte [eax+8], '1' mov byte [eax+9], 0xA0 mov byte [eax+10], '2' mov byte [eax+11], 0xA0 mov dx, 0x3D4 mov al, [esp-6] out dx, al mov dx, 0xCFC ; restore smramc mov al, [esp-5] out dx, al mov dx, 0xCF8 ; restore the old config value mov eax, [esp-4] out dx, eax mov al, 0x40 ; ack the periodic IRQ mov dx, 0x834 out dx, al mov dx, 0x830 in al, dx or al, 0x02 ; now ack the SMI itself and al, 0xBF out dx, al or al, 0x40 out dx, al rsm ; and leave SMM align 0x4 gdtr: db 0x27, 0x00 dd (gdt + 0xA8000) align 0x4 gdt: db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 db 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x93, 0xCF, 0x00 ; data segment db 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9B, 0xCF, 0x00 ; code segment db 0xFF, 0xFF, 0x00, 0x80, 0x0A, 0x9B, 0xCF, 0x00 ; code segment for trampoline TIMES 512-($-$$) DB 0 status: dd 0xAA55AA55 cstat: db 0x00