When you map linear memory to physical memory (using paging), you have to map the kernel so that when there is an interruption, the CPU can jump to the interrupt handler.
For the moment, I just mapped the kernel in the same position in both linear memory and physical memory (ie. my kernel is loaded by GRUB at 0x100000, so I identity map memory from 0x0 to 0x800000 or so)
What I don't understand is how you map the kernel to 0xdeadbeef or so: when an interruption is fired, the CPU jumps to offset 0xdeadb*** (corresponding to the interrupt handler)
But my asm interrupt handler will then jump to a C interrupt handler using (I think) a long jump (and consequently jump to offset 0x100***)
How could this work?
Memory mapping
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re:Memory mapping
If your kernel is mapped to some area in virtual memory, like 0xc0000000 or something like that, you have just to make the IDT point to those addresses.
What is probably going wrong is that your assembly code attempts to reference an 1MB-based address (0x10xxxx) instead of the higherhalf based address (0xdeadxxxx), which sounds like a section/linker script issue.
What is probably going wrong is that your assembly code attempts to reference an 1MB-based address (0x10xxxx) instead of the higherhalf based address (0xdeadxxxx), which sounds like a section/linker script issue.
- Kevin McGuire
- Member
- Posts: 843
- Joined: Tue Nov 09, 2004 12:00 am
- Location: United States
- Contact:
Re:Memory mapping
@CyberP1708:
You could use, IMO, a code stub written in ASM; that is linked in with the kernel for a BASE of 0x100000 and have it create a initial kernel page directory and higher tables.
The rest of the kernel sections need to be linked for the virtual address the kernel will actually execute at.
You are going to have to map the kernel tables into the user processes anyhow so the only potential waste would be the kernel directory if you are creating a microkernel (the kernel tables are global).
Try experimenting by writting a stub in assembler to create the simple initial kernel page directory and tables and use a directive to place it in a section called .stub then modify the linker script or linker command line options to BASE the section .stub at 0x100000 while making sure the base the .text, .data, and other appropriate sections with a the correct virtual address.
You will also need to create a temporary page table and a 4096 byte entry at 0x100000 for when the stub switches into virtual mode so it can make the last instruction to jump to the virtual address where you want the kernel to reside at. After that you could deallocate the page using some simple stub memory managment algorithms that coincide with the design for memory managment in your kernel or a very simple one that can be translated into the kernel's design once in virtual mode. I assure you none of this is overly complicated - you can do it.
So the summary is link your kernel for the virtual address, and link the stub for the 0x100000 address so it can help get the kernel loaded up high. ::)
You could use, IMO, a code stub written in ASM; that is linked in with the kernel for a BASE of 0x100000 and have it create a initial kernel page directory and higher tables.
The rest of the kernel sections need to be linked for the virtual address the kernel will actually execute at.
You are going to have to map the kernel tables into the user processes anyhow so the only potential waste would be the kernel directory if you are creating a microkernel (the kernel tables are global).
Try experimenting by writting a stub in assembler to create the simple initial kernel page directory and tables and use a directive to place it in a section called .stub then modify the linker script or linker command line options to BASE the section .stub at 0x100000 while making sure the base the .text, .data, and other appropriate sections with a the correct virtual address.
You will also need to create a temporary page table and a 4096 byte entry at 0x100000 for when the stub switches into virtual mode so it can make the last instruction to jump to the virtual address where you want the kernel to reside at. After that you could deallocate the page using some simple stub memory managment algorithms that coincide with the design for memory managment in your kernel or a very simple one that can be translated into the kernel's design once in virtual mode. I assure you none of this is overly complicated - you can do it.
So the summary is link your kernel for the virtual address, and link the stub for the 0x100000 address so it can help get the kernel loaded up high. ::)
Re:Memory mapping
There is, in fact, another problem
GRUB tells me "Selected item can't fit into memory" as it detects that some parts of the kernel are linked to 0xF0000000
GRUB tells me "Selected item can't fit into memory" as it detects that some parts of the kernel are linked to 0xF0000000
- Kevin McGuire
- Member
- Posts: 843
- Joined: Tue Nov 09, 2004 12:00 am
- Location: United States
- Contact:
Re:Memory mapping
You might _try_ , as I have never myself, setting the physical section address to something around the 1MB or 16MB mark depending on where you are loading the kernel as usual and just alter the virtual address IIRC.
physical virtual
.stub 0x100000 0x100000
.text 0x101000 0xE0000000
.data 0x102000 0xE0001000
..... ....
GRUB IMO should use the physical address field in each section in the ELF32 image instead of the virtual address field which the code is linked for.
GRUB tutorial
If GRUB still will not load that correctly then it may not work unfourtunatly, unless someone else knows how.
physical virtual
.stub 0x100000 0x100000
.text 0x101000 0xE0000000
.data 0x102000 0xE0001000
..... ....
GRUB IMO should use the physical address field in each section in the ELF32 image instead of the virtual address field which the code is linked for.
GRUB tutorial
Apparently GRUB will load by the physical address, and the virtual address repersents what the section is linked for.Kernel load address
GRUB reads the physical address (load address; LMA) of the kernel from the ELF file. This value must be
1. at or above 1 meg, and
2. below the end of physical RAM
If GRUB still will not load that correctly then it may not work unfourtunatly, unless someone else knows how.
Re:Memory mapping
That's what I was looking for
Thank you
But... it doesn't work :-\
Did someone test it?
I get a pagefault exception when jumping to StartInHigherHalf
Thank you
But... it doesn't work :-\
Did someone test it?
I get a pagefault exception when jumping to StartInHigherHalf