Page 1 of 1

Global descriptor table

Posted: Mon May 18, 2015 4:54 pm
by Reverted
Hello, I recently started to play with OS-Development. As tutorials suggested I am using GRUB multiboot to get booted kernel witch A20 line on and protected mode set on. Although I want to set my own GDT (for training). I read on wiki that extended memory starts at 0x01000000 address, and I set qemu to run with 3Gb of RAM (-m 3G switch). After GDT flush I want to use only upper memory and use only 1Gb of it (for code and data only for now). Here is my code for GDT flush (GAS synatx):

Code: Select all

.equ NULL_DESCRIPTOR,  0x0000000000000000

.equ CODE,          0x01C09A0000000000
.equ DATA,          0x01C0930000000000
.equ PLACE_HOLD1,          0x01C0930000000000
.equ PLACE_HOLD2,          0x01C09A0000000000
.section .data
     GDT:
        .quad NULL_DESCRIPTOR
        .quad CODE
        .quad DATA
        .quad PLACE_HOLD1
        .quad PLACE_HOLD2
    _GDT:
        .word 24
        .long GDT

.section .text

.global flushGDT
.type flushGDT, @function

flushGDT:
    lgdt _GDT
    xor %eax, %eax
    mov $0x10, %ax
    mov %ax, %ss
    mov %ax, %ds
    mov %ax, %gs
    mov %ax, %fs
    mov %ax, %es
    jmp $0x08 ,$leaveToKernel 
leaveToKernel:  
ret
Please don't mind PLACE_HOLD1 and PLACE_HOLD2, as name says it is just place holder for something ( probably TSS).
Problem with this code is that as soon as jump is performed CPU triple faults. I get that this is caused by trying to access invalid memory, but I do not get why RAM described in selectors is invalid. I will really appreciate your help in this matter.

Re: Global descriptor table

Posted: Mon May 18, 2015 6:45 pm
by SpyderTL
At first glance, I think your GDT size needs to be 23. If I remember correctly, the length should be -1...

Also, is the GDT pointer address 64-bit or 32-bit?

Edit: Also, where is this code loaded in memory? If you don't include this code's address in your code segment, you'll instantly make this code GPF, as it will no longer be available.

Re: Global descriptor table

Posted: Mon May 18, 2015 7:23 pm
by Octocontrabass
Reverted wrote:but I do not get why RAM described in selectors is invalid.
The CPU doesn't know what is and is not valid RAM. Trying to access RAM that doesn't exist will not cause a CPU exception.

Your first problem is assuming that there is 1GB of contiguous RAM available. While this may be true on the emulator you have chosen, it will not be true of all hardware. (Where's the fun in writing an OS that only works in emulators?)

Let's move on to your GDT. The fault happens when you jump to the new code segment, so there is probably something wrong there. Let's check out the value you're using for your code segment.

Code: Select all

01 C 0 9A 000000 0000
Base: 0x01000000
Limit: 0x00000FFF

The obvious problem is the limit. The fault probably occurs when you jump well outside the 4KiB limit you've specified.

The less obvious problem is the base. If you don't correct the jump destination to take into account the change in base address, you'll end up jumping somewhere other than where you intended and most likely fault soon after.


(And yes, the length should be 23, not 24.)

Re: Global descriptor table

Posted: Wed May 20, 2015 5:41 pm
by Reverted
Thanks for tips. I have made some changes in GDT and a linker script to be sure that code will be present in new segment. Here is the new code descriptor:

Code: Select all

.equ CODE_P0,          0x01409A0000000000
Here is part of liker script with new section:

Code: Select all

.upper_code ALIGN(0x01000000) : ALIGN(0x01000000)
{
	*(.leaveToKernel)
}
Also I changed code by putting

Code: Select all

.section .upper_code
before

Code: Select all

.leaveToKernel
label. Problem still occurs, triple fault after jump in to new segment. I am sure that memory described in descriptor is available. I am sorry for this beginner/silly questions but I got really confused and I have no idea where i gone wrong.

Re: Global descriptor table

Posted: Wed May 20, 2015 5:57 pm
by kzinti
Reverted wrote:ALIGN(0x01000000)
That can't possibly be right. Surely you meant to set the address for the section and not align on that crazy big number?

Re: Global descriptor table

Posted: Thu May 21, 2015 1:01 am
by Octocontrabass

Code: Select all

01 4 0 9A 000000 0000
Base: 0x01000000
Limit: 0x00000000

I fail to see how a one-byte code segment will be at all useful.

There's another problem I didn't mention in my previous post: how will "ret" function? Even if you do set up the stack to point to the same location as it was previously, the address it pops off the stack won't be correct because the segment base has changed.