LDT, GDT, access above 1mb
LDT, GDT, access above 1mb
Ok, I've got A20 enabled, a GDT with limits for Data and Code selectors as 0xFFFF. I've got a gets(char *str) function which normally works fine but as soon as the pointer str rises above 1mb the computer triple faults. I've got no paging and it works fine below 1mb. Under bochs it complains that the LDT = 0 (I haven't set it to anything). Is this a problem with my GDT or what? Please can someone give me a clue to what's wrong.
Thanks in advance
Thanks in advance
Re:LDT, GDT, access above 1mb
Let's get this clear: the limits on your code and data segments are 0xFFFF (= 64KB - 1), and you're complaining that you can't access memory above 1MB?
You probably made a typo there. You probably meant to say 0xFFFFF (= 1MB - 1). Now, isn't it obvious why, with limit=1MB-1, you can't access over 1MB?
The solution is to enable the Big bit in the code and data descriptors. With the Big bit set, the limit is interpreted as a number of 4KB pages instead of a number of bytes. Hence your 1MB limit becomes 4GB.
You probably made a typo there. You probably meant to say 0xFFFFF (= 1MB - 1). Now, isn't it obvious why, with limit=1MB-1, you can't access over 1MB?
The solution is to enable the Big bit in the code and data descriptors. With the Big bit set, the limit is interpreted as a number of 4KB pages instead of a number of bytes. Hence your 1MB limit becomes 4GB.
Re:LDT, GDT, access above 1mb
Do you mean bit 7 if so I have it set to CF hex which I think is the 'big bit' Is this ok?
Re:LDT, GDT, access above 1mb
My mistake; I should have said the Granularity (G) bit. The Big (B) bit makes code and stack segments 32-bit. For a 32-bit code segment you'll want G=1 and B=1.
The granularity bit is bit 23 of the second doubleword of a descriptor, which comes out as bit 7 of the 7th byte (if I've read the diagram in the Intel manual correctly). Note that the 7th byte is the last-but-one byte of an 8-byte descriptor.
For example, if you wanted limit=0xFFFFF, B=1 and G=1, you'd set the 7th byte to 0x0F | 0x40 | 0x80 = 0xCF, as you said.
The granularity bit is bit 23 of the second doubleword of a descriptor, which comes out as bit 7 of the 7th byte (if I've read the diagram in the Intel manual correctly). Note that the 7th byte is the last-but-one byte of an 8-byte descriptor.
For example, if you wanted limit=0xFFFFF, B=1 and G=1, you'd set the 7th byte to 0x0F | 0x40 | 0x80 = 0xCF, as you said.
Re:LDT, GDT, access above 1mb
So if that's right what is wrong. The only info I've got is what bochs said LDT = 0.
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:LDT, GDT, access above 1mb
bochs shouldn't complaint about the LDT being 0 unless you load one of the segment registers with x :: x&4==4 (the TI bit set)
Re:LDT, GDT, access above 1mb
Check the register output emitted when Bochs exits. You get a full segment descriptor cache output, including base, limit and G and B bits.
Re:LDT, GDT, access above 3FFFFF bytes
Sorry after more testing it turns out that if I point the pointer to 3FFFFF then it works for 1 char and then crashes. So I guess the problem is at 400000. Bochs gives this out:-
Thanks00005647190i[CPU ] -----------------------------------
00005647190i[CPU ] selector->index*8 + 7 = 12487
00005647190i[CPU ] gdtr.limit = 31
00005647190i[CPU ] fetch_raw_descriptor: GDT: index > limit
00005647190i[CPU ] | EAX=00000048 EBX=00000001 ECX=000b8140 EDX=00000068
00005647190i[CPU ] | ESP=00208f68 EBP=00208f9c ESI=003fffff EDI=00208f8e
00005647190i[CPU ] | IOPL=0 NV UP DI NG NZ NA PE CY
00005647190i[CPU ] | SEG selector base limit G D
00005647190i[CPU ] | SEG sltr(index|ti|rpl) base limit G D
00005647190i[CPU ] | DS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00005647190i[CPU ] | ES:0010( 0002| 0| 0) 00000000 000fffff 1 1
00005647190i[CPU ] | FS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00005647190i[CPU ] | GS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00005647190i[CPU ] | SS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00005647190i[CPU ] | CS:0018( 0003| 0| 0) 00000000 000fffff 1 1
00005647190i[CPU ] | EIP=001002c8 (001002c7)
00005647190i[CPU ] -----------------------------------
00005647243p[CPU ] >>PANIC<< fetch_raw_descriptor: LDTR.valid=0
00005647243i[SYS ] Last time is 1043172305
00005647243i[CPU ] protected mode
00005647243i[CPU ] CS.d_b = 32 bit
00005647243i[CPU ] SS.d_b = 32 bit
00005647243i[CPU ] | EAX=00000048 EBX=00000001 ECX=000b8140 EDX=00000068
00005647243i[CPU ] | ESP=00208f58 EBP=00208f9c ESI=003fffff EDI=00208f8e
00005647243i[CPU ] | IOPL=0 NV UP DI NG NZ NA PO CY
00005647243i[CPU ] | SEG selector base limit G D
00005647243i[CPU ] | SEG sltr(index|ti|rpl) base limit G D
00005647243i[CPU ] | DS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00005647243i[CPU ] | ES:0010( 0002| 0| 0) 00000000 000fffff 1 1
00005647243i[CPU ] | FS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00005647243i[CPU ] | GS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00005647243i[CPU ] | SS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00005647243i[CPU ] | CS:0018( 0003| 0| 0) 00000000 000fffff 1 1
00005647243i[CPU ] | EIP=0010029f (0010029e)
00005647243i[ ] restoring default signal behavior
00005647243i[CTRL ] quit_sim called
Re:LDT, GDT, access above 1mb
I don't know if this will help but 0x400000 is the 4MB Mark which means that paging will switch to the next page directory entry, are you using paging and do you have a valid page table entry for 4MB-8MB?
Daryl.
Daryl.
Re:LDT, GDT, access above 1mb
Thanks for all your help but the problem was in the bootsector(John Fine's bootf02). It wasn't so much a problem but I hadn't realized that it enabled paging. As I don't plan to use paging I don't know the exact problem but now I've switched to GRUB with no paging and everythings fine.
The problem's so simple I'm not sure whether to be ;D or :-[
The problem's so simple I'm not sure whether to be ;D or :-[
Re:LDT, GDT, access above 1mb
Disabling paging will fix your problem for now, so , but don't discount it completely. Soon in the future you should realise that paging will come in useful.
Re:LDT, GDT, access above 1mb
..
Last edited by Perica on Sun Dec 03, 2006 8:37 pm, edited 1 time in total.
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:LDT, GDT, access above 1mb
just give a look at the addresses bus on your motherboard ... see that #20 line, carryig the bit that becomes "1" when you reach 1MB ? see where it comes from ... there! at the chipset! a filter that enforces it to be 0 at startup !! This occurs regardless of whether the CPU will be in real or pmode the chipset just don't care. So you're better enabling that f**ing A20 gate or your spaceship will warp back from 0x0000000. And if by any chance you could reach 0x002f.ffff, be sure you'll be warped back at 0x0020.0000 at the next byte.Perica Senjak wrote: Hey,
I just got a few questions:
What's the use of the A20 Gate in ProtectedMode? Since it's only used for acessing more than 1mb of memory in RealMode, what does it do in ProtectedMode?
kiddying me, eh ? 8Gb with 32 lines for the addresses ? better stop thinking about it Moreover, you should remind yourself that the output of the segmentation unit is sent to the paging unit, not to the memory, and the virtual address space IS 32-bit wide regardless of the amount of memory installed.
The Max Limit a GDT Selector can have is 4Gb, but what if i set the Base to 0xFFFFFFFF (4Gb) -- Could i acess up to 8Gb of address space then?? Also, in ProtectedMode -- Are any devices mapped from the 3Gb mark to the 4Gb mark?
Now, what you can use to access more than 4GB of physical ram is the so-called Physical Size Extension (came with the Pentium PRO, iirc) that must be activated from the CR4 register (to be checked in the docs), but i haven't delved in the depth of it yet.
Re:LDT, GDT, access above 1mb
No; addresses will wrap round. If you've read my memory tutorials you might be aware of the GDT trick which uses address wraparound to avoid the need to enable paging early on.Perica Senjak wrote:The Max Limit a GDT Selector can have is 4Gb, but what if i set the Base to 0xFFFFFFFF (4Gb) -- Could i acess up to 8Gb of address space then??
Maybe (you can't say for sure). Any PCI video card I've seen has had its memory located just below 4GB.Also, in ProtectedMode -- Are any devices mapped from the 3Gb mark to the 4Gb mark?
Re:LDT, GDT, access above 1mb
..
Last edited by Perica on Sun Dec 03, 2006 8:37 pm, edited 1 time in total.