Memory Remapping
Re:Memory Remapping
Bochs has been under development for about six years by at least 25 people. I don't know how long you've been writing your kernel, but I'm sure you don't have 150 man-years work in there. The bug is almost certainly in your code.
-
- Member
- Posts: 1600
- Joined: Wed Oct 18, 2006 11:59 am
- Location: Vienna/Austria
- Contact:
Re:Memory Remapping
as tim says, bochs is well developed and debugged. It is to my knowledge not to be blamed for such errors.
peter, how do you build the idtr? How do you pass the adress of idt to idtr.base? It is something here because the highest two bytes are cut off. Do you do some bit shifting with the adress of the idt prior to passing it to idtr.base?
Just some debugging hints. I got ONE blank white hair in my left eyebrow due to such weird mistakes *lol*
peter, how do you build the idtr? How do you pass the adress of idt to idtr.base? It is something here because the highest two bytes are cut off. Do you do some bit shifting with the adress of the idt prior to passing it to idtr.base?
Just some debugging hints. I got ONE blank white hair in my left eyebrow due to such weird mistakes *lol*
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
BlueillusionOS iso image
Re:Memory Remapping
For some reason i can' upload code at the moment.
My IDTR set by
where the GDT and GDTPtr are
My IDTR set by
Code: Select all
; Set Global Descriptor Table here, this must be done PRIOR to Protected Mode
LGDT [GDTptr]
Code: Select all
GDT: ; our descriptors
; NULL descriptor
dw 0 ; limit 15:0
dw 0 ; base 15:0
db 0 ; base 23:16
db 0 ; type 15:8
db 0 ; limit 19:16, flags
db 0 ; base 31:24
; unused descriptor
dw 0
dw 0
db 0
db 0
db 0
db 0
; data segment descriptor
LINEAR_DATA_SEL EQU $-GDT
dw 0xFFFF ; limit 0xFFFF (1 meg, 4 gig)
dw 0x0 ; Set base address to 3Gb //base is 0 so set base address bits 15:0 to 0
db 0x20 ; //base is 0 so set base address bits 23:16 to 0
db 0x92 ; present, ring 0, data, expand-up, writable
db 0xCF ; page-granular (4 gig limit), 32-bit
db 0x80 ; base is 0 so set base address bits 31:24 to 0
; code segment descriptor
LINEAR_CODE_SEL EQU $-GDT
dw 0xFFFF ; limit 0xFFFF (1 meg, 4 gig)
dw 0x0 ; Set base address to 3Gb //base is 0 so set base address bits 15:0 to 0
db 0x20 ; //base is 0 so set base address bits 23:16 to 0
db 0x9E ; present, ring 0, code, non-conforming, readable
db 0xCF ; page-granular (4 gig limit), 32-bit
db 0x80 ; base is 0 so set base address bits 31:24 to 0
GDT_END:
GDTptr:
dw GDT_END - GDT - 1 ; GDT limit
dd (GDT + (0x7C00 - 0x40100000)) ; linear, physical address of GDT
-
- Member
- Posts: 1600
- Joined: Wed Oct 18, 2006 11:59 am
- Location: Vienna/Austria
- Contact:
Re:Memory Remapping
hmmm ....
to which adress do you link your kernel?
If you link your adress to 0x100000, then you have to do adress correcion the following way:
say start label= start32.
you link your kernel to 0xc0000000, but you load it to physical adress 0x100000,
then you make an constant: 0xbff00000. your start adress is virtually 0xc0000000, then you subtract the constant, and you 'll get 0x100000.
so you also do it with gdt adress (lgdt [gdtptr-0xbff000000]).
Furthermore ... you show your gdt code, and talked about idt?
to which adress do you link your kernel?
If you link your adress to 0x100000, then you have to do adress correcion the following way:
say start label= start32.
you link your kernel to 0xc0000000, but you load it to physical adress 0x100000,
then you make an constant: 0xbff00000. your start adress is virtually 0xc0000000, then you subtract the constant, and you 'll get 0x100000.
so you also do it with gdt adress (lgdt [gdtptr-0xbff000000]).
Furthermore ... you show your gdt code, and talked about idt?
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
BlueillusionOS iso image
Re:Memory Remapping
Sorry i meant GDT , As for the correction i thought i had done that. I subtract 0x40100000 from both the address of the GDT and from my jump i do to the kernel.
Peter
Peter
Re:Memory Remapping
Oh by the way i am linking my kernel to the 3Gb mark. The main problem i don't understand is why the GDT base is incorrect in Bochs i think this is the cause of all my problem sbut don't understand why its happening.
Peter
Peter
Re:Memory Remapping
1 man year implies 40 hours a week for a year. I really doubt these guys have dedicated thier entire lives to bochs. It is probably more like a couple hours a week - all in all I doubt more then 1 or 2 man years is wrapped up in it.Tim Robinson wrote: Bochs has been under development for about six years by at least 25 people. I don't know how long you've been writing your kernel, but I'm sure you don't have 150 man-years work in there. The bug is almost certainly in your code.
_mark()
-
- Member
- Posts: 1600
- Joined: Wed Oct 18, 2006 11:59 am
- Location: Vienna/Austria
- Contact:
Re:Memory Remapping
peter, you subtract less than necessary, i think. Have you tested this your calculation on a piece of paper?pskyboy wrote: Sorry i meant GDT , As for the correction i thought i had done that. I subtract 0x40100000 from both the address of the GDT and from my jump i do to the kernel.
Peter
I suggest you test this issue on a piece of paper, with your adress correction constant and f. ex. with 0xbff00000, when you load your kernel to physical 0x100000. Just an example.
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
BlueillusionOS iso image
Re:Memory Remapping
i have tried it both on paper and using the address as a constant still with no luck.
Peter
Peter
Re:Memory Remapping
Hey guys
i have fixed the problem with the GDT not loading the full 4Bytes for the base. It was infact a bug in bochs and i hacked the code and so it now works.
My next problem is that the jmp to clear the prefetch cache after switching to protected mode won't jump to the altered address as it will only jump to a maximum of a 16Bit value. Has anyone got any ideas how i get around this as i don't think i can start using 32Bit instructions till the prefetch has been cleared.
cheers
Peter
i have fixed the problem with the GDT not loading the full 4Bytes for the base. It was infact a bug in bochs and i hacked the code and so it now works.
My next problem is that the jmp to clear the prefetch cache after switching to protected mode won't jump to the altered address as it will only jump to a maximum of a 16Bit value. Has anyone got any ideas how i get around this as i don't think i can start using 32Bit instructions till the prefetch has been cleared.
cheers
Peter
Re:Memory Remapping
Could you explain the bug? Bochs' LGDT instruction works; after all, plenty of 'real' operating systems work under Bochs. Maybe you didn't have the right alignment on your GDTR structure. Does your code work on a real PC?
or similar.
This jump isn't to clear the prefetch queue; it's to load the CS selector. You will need to do a 32-bit far JMP. NASM should accept something like:My next problem is that the jmp to clear the prefetch cache after switching to protected mode won't jump to the altered address as it will only jump to a maximum of a 16Bit value. Has anyone got any ideas how i get around this as i don't think i can start using 32Bit instructions till the prefetch has been cleared.
Code: Select all
jmp far dword 8:pmode
Re:Memory Remapping
The function in Bochs that handles the LGDT for some reason only loaded bits 0-15, 16-23 and not bits 24-31 and it had a comment saying saying Top 8 bits is ignored.
I have put a post on the bochs developer board asking about this but for now i have altered the source code to load the full 32 bits in so i can do the relocation in the boot loader.
Peter
I have put a post on the bochs developer board asking about this but for now i have altered the source code to load the full 32 bits in so i can do the relocation in the boot loader.
Peter
Re:Memory Remapping
I'd say it was emulating the 286 behaviour when using LGDT in 16-bit mode, or in 32-bit mode with the A16 override. I'm looking at the 2.0.2 source right now, and it looks something like:
This conforms to what Intel put in their manual, under the LGDT instruction.
Conclusion: this isn't a bug. When using the 16-bit form of the LGDT instruction, you can only access 24 bits. The top 8 bits are ignored, and you can only access up to the 16MB mark.
Solution: don't put your LGDT above 16MB unless you want to use the 32-bit form of the instruction
Code: Select all
if (in_64bit_mode)
{
// do 64-bit stuff
}
else if (in_32bit_mode)
{
gdtr.limit = limit_16;
gdtr.base = base0_31;
}
else // 16-bit instruction
{
gdtr.limit = limit_16;
gdtr.base = (base16_23 << 16) | base0_15;
}
Conclusion: this isn't a bug. When using the 16-bit form of the LGDT instruction, you can only access 24 bits. The top 8 bits are ignored, and you can only access up to the 16MB mark.
Solution: don't put your LGDT above 16MB unless you want to use the 32-bit form of the instruction
-
- Member
- Posts: 1600
- Joined: Wed Oct 18, 2006 11:59 am
- Location: Vienna/Austria
- Contact:
Re:Memory Remapping
the following i do not understand: why for gods sake is bochs to be blamed for everything and all?
This problem you have, peter, you can solve easily: set up a temporary gdt in the boot loader and load the proper gdtptr there as well as perform the necessary pmode rituals prior to the jump to your kernel.
In kernel initialization, you can set op a gdt in a 32 bit environment and lgdt will stuff without any problems the 32 bit adress of the new gdt into gdtr.
It is simple, it is easy and it is a chicken and egg thingy.
This problem you have, peter, you can solve easily: set up a temporary gdt in the boot loader and load the proper gdtptr there as well as perform the necessary pmode rituals prior to the jump to your kernel.
In kernel initialization, you can set op a gdt in a 32 bit environment and lgdt will stuff without any problems the 32 bit adress of the new gdt into gdtr.
It is simple, it is easy and it is a chicken and egg thingy.
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
BlueillusionOS iso image
Re:Memory Remapping
Yeah so i basically i have come back to having a second stage in my boot processes which is what i was originally going to do. As for the intel documentation the information i found on the LGDT specified that it loaded a 32Bit base address.
Well people seemed to be getting quite annoyed on this board so i will join in with this. Why the hell did no one tell me that i would need to set the LGDT from 32Bit mode to load my kernel at the 3Gb mark. Maybe thia should go into your memory managment turtorial Tim if this is indeed the correct way to do it. Also while im at it i noticed in your tutorial you talk about loading the kernel at 1Mb and make it appear at 3Gb but you then suddenly change from 0x100000 which is 1Mb to 0x1000000 16Mb. The calculations for the base though is correct for 16Mb so i was just wondering if this was deliberate?
Peter
Well people seemed to be getting quite annoyed on this board so i will join in with this. Why the hell did no one tell me that i would need to set the LGDT from 32Bit mode to load my kernel at the 3Gb mark. Maybe thia should go into your memory managment turtorial Tim if this is indeed the correct way to do it. Also while im at it i noticed in your tutorial you talk about loading the kernel at 1Mb and make it appear at 3Gb but you then suddenly change from 0x100000 which is 1Mb to 0x1000000 16Mb. The calculations for the base though is correct for 16Mb so i was just wondering if this was deliberate?
Peter