proto639 wrote:My bad about the push, I was testing out some other methods I saw.
How big are pages usually? The tutorial I saw used 2MB pages, also where do you see the zero segment limits? I can't really read the GDT all that well, apologies.
Pages are normally 4kB. You can use pages larger than that (namely 2MB and 1GB pages), but those are huge pages, and there are limitations to their use. They cannot span areas with multiple memory types, for one thing. Most OSes implement 4kB paging, with optional use of huge pages if the situation permits, and having a consistent memory type is one of those requirements. In order to test for that, you'd need to worry about MTRRs, so maybe you should skip that for now and only do the 4kB paging.
The segment limit is part of the GDT entry, namely the low 16 bits, bits 48-51, and the G bit (bit 55). They set how big the segment is (more exactly: They set the highest offset in the segment.). I also at first didn't understand your segments. I am used to looking at them in hex now, because the fields do line up well with 4-bit boundaries. You know, it is basically
Where a is the base address, l is the limit, f is the flags nibble (the G, D, L, and AVL bits), p is the permissions nibble (the P, DPL, and S fields), and t is the type nibble. The GDT you have in your code amounts to:
Code: Select all
section .rodata
gdt64:
dq 0
.code: equ $ - gdt64
dq 0x00209a0000000000
.data: equ $ - gdt64
dq 0x0000920000000000
.pointer:
dw .pointer - gdt64 - 1
dq gdt64
And if you load the second one in 32-bit mode (which you do), then you get a segmentation fault for accessing any data item beyond offset 0. But it is easily fixed if you just change it to
Code: Select all
.code: dq 0x00af9a000000ffff
.data: dq 0x00cf92000000ffff
It takes the exact same amount of space, but now the limit is 4GB. Don't worry, once you get to 64-bit mode, the limit will be ignored.