Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
I'm trying to make my kernel into a higher half kernel. The way I'm trying to do this is with Tim Robinsons GDT trick (set GDT entries at 0x40100000 and link the kernel so it uses a base adress of 3GB=0xc0000000 but load it at 1MB=0x00100000 so the adresses get translated to 0xc0000000 + 0x40100000 = 0x00100000).
I have some trouble. I'm trying to debug the kernel with the bochs debugger. It seems that I am unable to load the GDT. I have added this assembly entry point before jumping to my kernel:
global _start
extern centry ; where the C code begins (my former entry point)
_start:
lgdt [GDTstart + 0x40100000]
add esp, 4 ; instead of pushing (esp + 4) we can increase the stack pointer: we wont be returning from the kernel anyway
call centry
GDTstart:
; descriptor / null entry
dw GDTend - GDTstart - 1
dd GDTstart
dw 0
; Code segment
dw 0xffff ; Limit address low
dw 0 ; Base low
db 0x10 ; Base high-low
db 10011010b ; Access byte
db 11001111b ; Granularity byte
db 0x40 ; Base high-high
; low segment
dw 0xffff ; Limit address low
dw 0 ; Base low
db 0x10 ; Base high-low
db 10010010b ; Access byte
db 11001111b ; Granularity byte
db 0x40 ; Base high-high
GDTend:
I uploaded a screenshot of Bochs before and after loading the GDT:
Stupid. The adress stored in the null descriptor is somewhere after the third gigabyte, I need to change that.
EDIT: Fixed that, but it still doesn't work. The problem seems to be that the 'overflow' on which the trick relies doesn't work (I don't have any hard evidence for this, but Bochs shows registers with space for 8 bytes or 64 bits, and I found this related topic: I seem to be having the same problem).
1. This is a nasty hack, and I don't know why anyone would do it (A paging based higher-half is far simpler)
2. The value used in the GDT base isn't being corrected.