flat assembler
Message board for the users of flat assembler.
Index
> OS Construction > Going back from protected to real mode. |
Author |
|
0x4e71 13 Aug 2006, 17:23
if you want to go back to real mode you also have to update cr0.
|
|||
13 Aug 2006, 17:23 |
|
Trolek 15 Aug 2006, 11:15
I did some changes and my kernel is going now into real mode. Maybe this will be usefull to someone in future.
Code: format elf executable at 1024*1024 entry _kernel MB_4KBPAGE_ALIGN = 1 shl 0 MB_MEMORY_INFO = 1 shl 1 MB_HEADER_MAGIC = 0x1BADB002 MB_HEADER_FLAGS = MB_4KBPAGE_ALIGN or MB_MEMORY_INFO MB_CHECKSUM = -MB_HEADER_MAGIC-MB_HEADER_FLAGS SEGMENT_RING0 = 10010000b SEGMENT_RW = 0010b SEGMENT_RE = 1010b SEGMENT_4KB = 1000b SEGMENT_USE32 = 0100b macro GDT_ITEM number,limit,base,access,granularity { Gdt_item#number: .limit_low dw limit and 0xFFFF .base_low dw base and 0xFFFF .base_middle db (base shr 16) and 0xFF .access db access .gran db ((limit shr 16) and 0x0F) or ((granularity) shl 4) .base_high db (base shr 24) and 0xFF } segment multiboot_header: .magic dd MB_HEADER_MAGIC .flags dd MB_HEADER_FLAGS .checksum dd MB_CHECKSUM _kernel: mov esp, kStack ; Load new GDT and set segment registers. lgdt [Gdt] mov ax, GDT_RING0_DATA mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax ; Flush CS. jmp GDT_RING0_CODE : .pmode_flush .pmode_flush: ; Load real mode IDT. lidt [rmIdtr] ; Copying real mode code to under 1MB. mov edi, 0x7C000 mov esi, RealModeCode mov ecx, length.RealModeCode rep movsb ; Jumping to segment with 64kb limit. Base is set to .rmode_flush. jmp GDT_RMODE_CODE : 0 .rmode_flush: org 0 use16 mov ax, GDT_RMODE_DATA mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax ; Cleaning PE bit in cr0. mov eax, cr0 and al, not 1 mov cr0, eax ; Jumping to 0x7C000. jmp 0x7C00 : 0 org $ + _kernel.rmode_flush use32 RealModeCode: org 0 use16 ; Setting segment registers. mov ax, cs mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax sti mov ax,0x4F02 mov bx,0x4112 int 10h cli hlt length.RealModeCode = $ org $ + RealModeCode use32 rmIdtr: .size dw 1023 .addr dd 0 Gdt: .size dw Gdt_size .addr dd Gdt_array Gdt_array: GDT_ITEM 0, 0, 0, 0, 0 GDT_RING0_CODE = $ - Gdt_array GDT_ITEM 1, 0xFFFFF, 0, SEGMENT_RING0 or SEGMENT_RE, SEGMENT_4KB or SEGMENT_USE32 GDT_RING0_DATA = $ - Gdt_array GDT_ITEM 2, 0xFFFFF, 0, SEGMENT_RING0 or SEGMENT_RW, SEGMENT_4KB or SEGMENT_USE32 GDT_RMODE_CODE = $ - Gdt_array GDT_ITEM 3, 0xFFFF, _kernel.rmode_flush, SEGMENT_RING0 or SEGMENT_RE, 0 GDT_RMODE_DATA = $ - Gdt_array GDT_ITEM 4, 0xFFFF, _kernel.rmode_flush, SEGMENT_RING0 or SEGMENT_RW, 0 Gdt_size = $ - Gdt_array - 1 segment rb 1024 kStack: |
|||
15 Aug 2006, 11:15 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.