Implementing

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.
beyondsociety

Implementing

Post by beyondsociety »

1. Load your kernel in physical memory starting at 1MB. Already done.
2. Have no paging at start-up, but a kernel code and data segment that has a base such as 1MB == 1GB(0x4000.0000)
3. Enable paging mapping logical linear address 0x4000.0000 -> to physical addresses 0x0010.0000 ->
4. Reset the base of kernel code and data segment so that you have a flat_mode kernel.
2. Which base of the GDT?

Code: Select all

FLAT_CODE_SEL equ $-gdt
dw  0xFFFF       ; Limit
dw  0            ; Base 15:0
db  0            ; Base 23:16
db  0x9A
db  0xCF
db  0            ; Base 31:24
What does part 3 mean?
beyondsociety

Re:Implementing

Post by beyondsociety »

Forget about the first question as I am going to go in the way of using position independent code instead of using the gdt trick until enabling paging in my kernel. My problem is that I Am getting this error in bochs:
jump_protected: S=1, descriptor not executable

I am trying to reload my gdt with the segment registers and on jumping to the new code, it dumps and gives me this error. Does anybody know what this means?
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Implementing

Post by Pype.Clicker »

It means that BOCHS doesn't like your code descriptor. The most likely error is that when reprogramming the GDT you loaded a wrong address for it. (check out with a dump_cpu -- debugging bochs tricks are available in .:QuickLinkz:.)
beyondsociety

Re:Implementing

Post by beyondsociety »

Ive done some tests and havent figured out my problem, though I have gotten farther then previously. Indeed there is something wrong with my gdt descriptors but I cannot find out what the problem is with it.

I am now getting a load_seg_reg: segment not present error in bochs. When I ran the bochs debugger and set the Virtual break point to the EIP value thats faulting, then did a dump_cpu, I noticed something weird about the base of my gdtr. Its shows: gdtr base (0xffffffff), gdtr limit (0xffff). Strange how the base is larger than the limit of the gdtr.

I am virtualy linking my code to 0x40000000 (1GB) and physically loading it to 0x100000 (1MB) from the bootloader. Code is attached below. Thanks in advance for any help.

It tripple faults when it gets to the: mov ds, ax part of reloading the gdt in my code.

[attachment deleted by admin]
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Implementing

Post by Pype.Clicker »

beyondsociety wrote: I noticed something weird about the base of my gdtr. Its shows: gdtr base (0xffffffff), gdtr limit (0xffff). Strange how the base is larger than the limit of the gdtr.
this sounds like if you loaded the GDT registers with a memory region that was not valid (for instance, if you have lgdt[0xC000_0000], you're likely to see uninitialized memory there, which is all read as "0xff" bytes ...)

Remember that the address given to LGDT is processed (iirc) through the current DS segment before it resolves in a memory location that holds the linear address and the size of the GDT ...

Maybe you should set a breakpoint to your LGDT instruction and see what's going on there.
beyondsociety

Re:Implementing

Post by beyondsociety »

Maybe you should set a breakpoint to your LGDT instruction and see what's going on there.
0X008:0010002a: lgdt DS:40002018

EAX: 0X3544da2a, EBX: 0X10, ECX: 0X110000, EDX: 0X3f2, EBP: 0X0, ESI: 0Xc0100000,
EDI: 0Xffe4, ESP: 0Xfffe, EFLAGS: 0x46, EIP: 0X10002a

CS:S = 0X08, DL = 0Xffff, DH = 0Xcf9a00, valid = 7
SS:S = 0x10, DL = 0xffff, DH = 0xcf9300, valid = 7
DS:S = 0X10, DL = 0Xffff, DH = 0Xcf9200, valid = 1
ES:S = 0x10, DL = 0xffff, DH = 0xcf9300, valid = 1
FS:S = 0x10, DL = 0xffff, DH = 0xcf9300, valid= 1
GS:S = 0x10, DL = 0xfff, DH = 0xcf9300, valid = 1

gdtr: base = 0x7c46, limit = 0x17

0008:00100031: mov ax, 0010

EAX: 0x3544da2a, EBX: 0x10, ECX: 0x110000, EDX: 0x3f2, EBP: 0x0, ESI: 0xc0100000,
EDI: 0xffe4, ESP: 0xfffe, EFLAGS: 0x46, EIP:0x100031

CS:S = 0x08, DL = 0xffff, DH = 0xcf9a00, valid = 1
Rest are the same.

gdtr: base = 0xffffffff, limit = 0xffff
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Implementing

Post by Pype.Clicker »

err ... waitaminute ...
Does the first dump_cpu output dump the state of your CPU *before* executing lgdt, or *after* executing it ?
beyondsociety

Re:Implementing

Post by beyondsociety »

Does the first dump_cpu output dump the state of your CPU *before* executing lgdt, or *after* executing it ?
What do you mean by this?
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Implementing

Post by Pype.Clicker »

well, what i need to know is if "gdtr: base = 0x7c46, limit = 0x17" was your previously programmed GDT or your new GDT.

i would rather say it was the old one, and that trying to access [0x4000_2018] memory area is a mistake, because that was out of the scope of valid memory ...

maybe you need

Code: Select all

  lgdt [gdt_table+esi]
beyondsociety

Re:Implementing

Post by beyondsociety »

Q. I know this sounds like a stupid question, but which way is the right way to reload the GDT. Some code does it the first way and others does it the second. Cause this might shed some light on what my problem might be.

Code: Select all

lgdt [gdt_table]
jmp FLAT_CODE_SEL:new_gdt

new_gdt:  
mov ax, FLAT_DATA_SEL
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax
or

Code: Select all

lgdt [gdt_table]

mov ax, FLAT_DATA_SEL
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax

jmp FLAT_CODE_SEL:new_gdt

new_gdt:
Curufir

Re:Implementing

Post by Curufir »

They're the same, the jump is only there to clear the prefetch queue and set code selector.

As for this not executable error:

I realise this is elementary and you've probably already checked it, but did you set that selector's type to be code?
beyondsociety

Re:Implementing

Post by beyondsociety »

I realise this is elementary and you've probably already checked it, but did you set that selector's type to be code?
I checked this and its correct to my knowledge.

Code: Select all

Access Type: P=1,DPL=0,DT=0,S=1,1010
= 0x9A for code segment.
S=1: code/data segment, 0: system segment

The error is: jump_protected: S=1, not executable.
Which doesnt make sense.

Type should be:

Code: Select all

E=1,E/C=0,W=1,A=0: 1010
Does anybody know whats wrong?
beyondsociety

Re:Implementing

Post by beyondsociety »

maybe you need
lgdt [gdt_table+esi]
I added this and now I get: jump_protected: dpl > cpl
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Implementing

Post by Pype.Clicker »

beyondsociety wrote:
maybe you need
lgdt [gdt_table+esi]
I added this and now I get: jump_protected: dpl > cpl
which seems a "better" fault, imho. What do the GDTR look like before you take the jump, now ?
do GDTR.base have the right value ?
beyondsociety

Re:Implementing

Post by beyondsociety »

which seems a "better" fault, imho. What do the GDTR look like before you take the jump, now ?
do GDTR.base have the right value ?
Before: gdtr: base = 0x7c46, limit = 0x17
After: gdtr: base = 0x40002000, limit = 0x17

Its now loaded to correct address, except for the 2000 which I dont know where that comes from. Could it be whats in my gdt? In all of my code, I never load the gdt to a certain address.

When it gets to the jmp 0x08:0x40000000,
ds:s=0x10, dl=0xffffffff, dh=0xffdfffff, valid=1

Previously it was,
ds:s=0x10, dl=0xffff, dh=0xcf93200, valid=7
Post Reply