a mobius question

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.
Chris Giese

Re:a mobius question

Post by Chris Giese »

jarlin wrote:
yeah, that's my problem wich i don't know how to solve. How can i link the kernel,in elf32 format, to work at 0xC0000000 virutal address, but load it at 0x100000??
Use AT() in the linker script, e.g.
http://my.execpc.com/~geezer/osd/code/krnl1m.ld
but change "LS_Virt" to 0xC0000000

Of course, the kernel must set up address translation once it starts; either paging or segment-based. It's probably best to do this in assembly language, before jumping to C.

Segment-based address translation isn't too difficult: http://my.execpc.com/~geezer/osd/gotchas/boot.asm
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:a mobius question

Post by Candy »

jarlin wrote:
yeah, that's my problem wich i don't know how to solve. How can i link the kernel,in elf32 format, to work at 0xC0000000 virutal address, but load it at 0x100000??
Since ELF docs themselves say that the physical address should be disregarded on systems where they have no obvious use (static partitioning systems by example), you do not pay any attention at it. If you want to load it at 0x100000, just load it there (note: realmode loaders cannot load to that address without enabling A20, and if you did they cannot load more than 64K-16 bytes.

Then use the info from the program header to determine where to put what, so if you want it to run at 0xC0000000 (and use -Ttext=0xC0000000) then you are going to have to do some black magic. First of all, the easiest way is not to use nmagic or omagic, since they prevent the code from being page-aligned in the file. Then you relocate it all so that 0x100000 actually comes out at 0xBFFFF000, putting the ELF header before the page itself, and the code starting at (yessir) 0xC0000000. You can relocate it with paging OR segmentation. For paging, set up page tables, page directory + entries for all those pages (3 page tables of entries if it's big), and for segmentation, make a segment with the base address of 0x40100000 (as described by somebody in his tutorial, forgot whose it was) to make the address end up at 0x00100000 (NOTE: this method STRONGLY disadvised by me. It breaks (probably) with every processor having more than 32 address lines, such as the PPro and further, and the AMD K6 series and further).

For a paging example, wait until I have my code online :)

(have decided to go open source anyway).
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:a mobius question

Post by Pype.Clicker »

Candy wrote:
jarlin wrote: NOTE: this method STRONGLY disadvised by me. It breaks (probably) with every processor having more than 32 address lines, such as the PPro and further, and the AMD K6 series and further.
That would be a wise suggestion for generic-purpose code. However, in the case of a bootloader, having a architecture-specific solution is not an issue. Most other systems (Sparc, PowerPC, etc) do not have something like realmode and you're likely to have a very different loader for them.

For IA-32 systems that have more address lines (i.e. those that have the Physical Size Extension and allow for 36bits or physical addresses), the address space remains of 32 bits, and the highest 4 bits are defined by page tables content (iirc), thus the segmentation trick (that applies *before* paging is applied) will still work as the *linear* address will wrap around in any way.
Post Reply