Hooray!!
Now, 0SOS can execute the 32-bit code as well.
That mean, We can use 32bit general registers.
Like eax, esi registers.
I’m so glad.
Look at this:
As you can see, It is completely working.
If you say like this: “I can simply do it, using C Language”
Please, Close this post.
Anyway, I’ve made an effort for understanding.
And success!
Dammit…
Especially, segment table, the range of used memory and stack makes me a headache.
First of all, Following steps are the description for change 16-bit real-mode to 32-bit protect-mode:
First, Organize a GDT table, and then addressing GDT to the processor.
That table’s first elements is NULLDescriptor that is filled 0 in Descriptor element.
Second, We need to define descriptor. Me and author insert Code and Data segment descriptor in GDT.
This step makes me much harder to understand.
I guess code and data descriptor shouldn’t overlap. Something weird is the base address of descriptor and access limitation are the same.
But I just miss understanding.
Dammit…
Eventually, on the current code, specifically on the defined table, segment descriptors doesn’t sperate the code and data area of the memory.
Both of them could address the 0~4GB memory area.
Also, the stack couldn’t be overlapped because stack grows downwards from the top.
(Because that have a 64kb limit. You should see esp and ebp in the code)
So We can find an expression of calculation for a relative address on the example code.
Like (LABEL - $$ + 0x10000).
Anyway, I understand completely.
And then, Third, Set up CR0 Register that manages operating mode.
You can see the table of the setup value below.
And If you want to find more, google it.
After then, You just jump to the 32-bit code area.
Yeah!
Anyway below code is the entry point of my kernel for the 32-bit system:
[ORG 0x00]
[BITS 16]
SECTION .text
START:
mov ax, 0x1000
mov ds, ax
mov es, ax
cli ;Ignore Interrupt
lgdt[GDTR]
; Now Switch Protected Mode.
;
; CR0 Register
; Summary:
; Disable Paging, Disable Cache, Internal FPU, Disable Align Check
;
; fields:
;
; |PG|CD|NW| | | | | | | | | | |AM| |WP|
; 31---------------------------------------------16
; | 0| 1| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0|
;
; | | | | | | | | | | |NE|ET|TS|EM|MP|PE|
; 15----------------------------------------------0
; | 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 1| 1| 1| 0| 1| 1|
;
; 0b01000000000000000000000000111011
; 0x4000003B
;
mov eax, 0x4000003B
mov cr0, eax
jmp dword 0x08 : (PROTECTEDMODE - $$ + 0x10000)
; Following Code Now Protected Mode
[BITS 32]
PROTECTEDMODE:
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
mov esp, 0XFFFE
mov ebp, 0XFFFE
push (SWITCHMESSAGE - $$ + 0x10000)
push 2
push 0
call PRINT
add esp, 12
jmp $
PRINT:
push ebp
mov ebp, esp
push esi
push edi
push eax
push ecx
push edx
mov eax, dword [ebp + 12]
mov esi, 160
mul esi
mov edi, eax
mov eax, dword[ebp + 8]
mov esi, 2
mul esi
add edi, eax
mov esi, dword[ebp + 16]
.PRINTLOOP:
mov cl, byte[esi]
cmp cl,0
je PRINTEND
mov byte[edi + 0xB8000], cl
add esi,1
add edi,2
jmp .PRINTLOOP
PRINTEND:
pop edx
pop ecx
pop eax
pop edi
pop esi
pop ebp
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;; DATA AREA
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
align 8, db 0
dw 0x0000 ;For Align
GDTR:
dw GDTREND - GDT -1
dd GDT - $$ + 0x10000
GDT:
NULLDescriptor:
dw 0x0000
dw 0x0000
db 0x00
db 0x00
db 0x00
db 0x00
CODEDescriptor:
dw 0xFFFF ; Limit[15:0]
dw 0x0000 ; Base[15:0]
db 0x00 ; Base[23:16]
db 0x9A ; P = 1, DPL = 0, Code Segment, Execute/Read
db 0xCF ; G = 1, D = 1, L = 0, Limit [19:16]
db 0x00 ; Base[31:24]
DATADescriptor:
dw 0xFFFF ; Limit
dw 0x0000 ; Base
db 0x00 ; Base
db 0x92 ; P=1, DPL =0, Data Segment, Read/Write
db 0xCF ; G= 1, D= 1, L= 0, Limit
db 0x00 ; Base
GDTREND:
SWITCHMESSAGE: db 'Switch Success. Now Running 32bit Protected Mode.',0
times 512 - ( $ - $$) db 0x00
It won’t hard code to understand. Also, we should change the sector number to 1 for the bootloader.
Surely, real-mode and protected-mode are different for addressing memory.
Well, Well, I’m excited about how much complex on IA-32e mode.
And currently, paging is disabled but if it is enabled…
Anyway, I’ve made a table of the code.
On the vim:
I’m not sure above table correct.
well, Worke is done for 32bit! Let’s write kernel code.