Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- bits 16
- ORG 0x7c00
- start:
- xor ax, ax
- mov ds, ax
- ; Enter 32-bit protected mode
- cli
- lgdt [gdt.gdtr]
- mov eax, cr0
- or eax, 1
- mov cr0, eax
- jmp CODE32_PL0_SEL:.prot32mode
- bits 32
- .prot32mode:
- mov eax, DATA32_PL0_SEL
- mov ds, eax
- mov es, eax
- mov fs, eax
- mov gs, eax
- mov ss, eax
- mov esp, 0x90000
- lidt [idt.idtr]
- ; 32-bit Protected mode code here!!!
- mov bx, 0xd20
- ; Start switching back to real mode
- ; Must use a 16-bit code segment and enter 16-bit
- ; Protected mode FIRST.
- jmp CODE16_PL0_SEL:.prot16mode
- bits 16
- .prot16mode:
- ; Load the segment registers with 16-bit descriptors
- mov ax, DATA16_PL0_SEL
- mov ds, ax
- mov es, ax
- mov fs, ax
- mov gs, ax
- mov ss, ax
- ; Leave 16-bit protected mode back to real mode
- lidt [idtr_real]
- mov eax, cr0
- and al, ~1
- mov cr0, eax
- jmp 0:.realmode
- .realmode:
- ; Set up a stack and set the real mode segment registers
- xor ax, ax
- mov ds, ax
- mov es, ax
- mov ss, ax
- mov sp, 0x7c00
- sti ; Enable interrupts(not necessary for this code)
- cld ; Set DF (Direction Flag) forward.
- mov bx, 0xd00
- mov si, realmodestr
- call print_string_16
- hltloop:
- hlt
- jmp hltloop
- realmodestr: db "Back in real mode!", 0
- ; Function: print_string_16
- ; Display a string to the console on display page 0
- ;
- ; Inputs: SI = Offset of address to print
- ; Clobbers: AX, BX, SI
- print_string_16:
- mov ah, 0x0e ; BIOS tty Print
- xor bx, bx ; Set display page to 0 (BL)
- jmp .getch
- .repeat:
- int 0x10 ; print character
- .getch:
- lodsb ; Get character from string
- test al,al ; Have we reached end of string?
- jnz .repeat ; if not process next character
- .end:
- ret
- ; Macro to build a GDT descriptor entry
- %define MAKE_GDT_DESC(base, limit, access, flags) \
- dq (((base & 0x00FFFFFF) << 16) | \
- ((base & 0xFF000000) << 32) | \
- (limit & 0x0000FFFF) | \
- ((limit & 0x000F0000) << 32) | \
- ((access & 0xFF) << 40) | \
- ((flags & 0x0F) << 52))
- ; GDT structure
- align 4
- gdt:
- CODE32_PL0_SEL EQU .code32_pl0 - .start
- DATA32_PL0_SEL EQU .data32_pl0 - .start
- CODE16_PL0_SEL EQU .code16_pl0 - .start
- DATA16_PL0_SEL EQU .data16_pl0 - .start
- .start: MAKE_GDT_DESC(0, 0, 0, 0)
- ; Null descriptor
- .code32_pl0: MAKE_GDT_DESC(0, 0x00ffffff, 10011010b, 1100b)
- ; 32-bit code, privilege level 0, gran=page, limit 0xffffffff
- .data32_pl0: MAKE_GDT_DESC(0, 0x00ffffff, 10010010b, 1100b)
- ; 32-bit data, privilege level 0, gran=page, limit 0xffffffff
- .code16_pl0: MAKE_GDT_DESC(0, 0x0000ffff, 10011010b, 0000b)
- ; 16-bit code, privilege level 0, gran=byte, limit 0x0000ffff
- .data16_pl0: MAKE_GDT_DESC(0, 0x0000ffff, 10010010b, 0000b)
- ; 16-bit data, privilege level 0, gran=byte, limit 0x0000ffff
- .end:
- ; Protected mode GDT record
- .gdtr:
- dw .end - .start - 1 ; limit (Size of GDT - 1)
- dd .start ; base of GDT
- ; Protected mode IDT
- idt:
- .start:
- ; This should be filled in with proper interrupt handlers
- .end:
- ; Protected mode IDT record
- .idtr:
- dw .end - .start - 1 ; limit (Size of GDT - 1)
- dd .start ; base of GDT
- ; IDTR for REAL Mode
- idtr_real:
- dw 0x3ff ; Real mode IVT is 0x3ff+1 bytes in size
- dd 0 ; Real mode IVT starts at bottom of memory
- ; Pad boot sector to 510 bytes and add 2 byte boot signature for 512 total bytes
- TIMES 510-($-$$) db 0
- dw 0xaa55
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement