Page 1 of 1
How to avoid or compensate moved entry points
Posted: Thu Jun 07, 2012 4:23 pm
by FauserneEist
Hi,
I ran into the following problem today: I have a long mode kernel with working screen output, a working gdt. If I now link my IDT code object file, without calling any of its functions, bochs triple faults me. I think I isolated the error: In order to get to the kernel_main Function located at 0xFFF...c150 my bootstrap code long jumps to that address. According to objdump, the kernel_main function is located there. But whenever I run bochs, the code of the kernel_main seems to be moved 0x12 units further down. The entry point should be located at 0x100000 but the first instruction it executes is at 0x10003F.
Do you need any more information or are there any suggestions, how I can fix the problem?
TIA
Re: How to avoid or compensate moved entry points
Posted: Thu Jun 07, 2012 4:34 pm
by bluemoon
If you use ELF, the entry address is on the program header and you don't need to hardcode it on the loader.
Re: How to avoid or compensate moved entry points
Posted: Thu Jun 07, 2012 4:41 pm
by Combuster
If there's indeed a difference between where your code is linked and where it gets loaded, your compilation instructions and other bootstrap code are probably wrong. An interesting hint to the problem would be to find out what ended up in the space where you expected something else.
As for diagnostics on our side, we need the compilation commands, and the linker scripts, multiboot headers, and bootloader code for as far as you use them - basically everything we need to reproduce the problem.
Re: How to avoid or compensate moved entry points
Posted: Fri Jun 08, 2012 12:29 am
by FauserneEist
I use GRUB2 as a bootloaders, so I think I can rule this one out as an error source...
My Makefile looks as follows:
http://ideone.com/wABFg
Linker script:
http://ideone.com/N67Gj
MB and bootstrap:
http://ideone.com/Nzf4B
Main C function:
http://ideone.com/1sIbv
The IDT Code is similar to what JamesM did in his Tutorial, only adapted to fit long mode requirements.
objdump --disassemble-all kernel.bin gives me the following output:
http://ideone.com/AjjXL
The jump instruction at line 66 jumps to the kernel_main function's address (line 382), so far everything looks good.
When I start bochs, the jump address is still 0xffffffff8010c150 but the code at this position is now the code that was in position 0xffffffff8010c141 (Line 372) of the objdump output, so basically it was moved down by 0xf.
Re: How to avoid or compensate moved entry points
Posted: Fri Jun 08, 2012 2:51 am
by Combuster
What looks like the most likely error, is that you are passing an ELF file with a multiboot tag formerly known as the A.OUT kludge. An ELF file contains an index of sections and locations where to load them. The a.out kludge does the same, but expects that all sections appear with a 1:1 mapping from file to memory. ELF is smarter than that, sees that you're aligning on a 4096-byte boundary, and strips out the gaps because the headers can reconstruct them. It might even freely put your sections in a different order in the file.
GRUB sees the A.out part, cuts off everything stored before the multiboot header (because that's where you say your kernel starts), then copies the kernel size from file to memory, including the lack of gaps and the sections in a possibly wrong order.
Re: How to avoid or compensate moved entry points
Posted: Fri Jun 08, 2012 3:19 am
by FauserneEist
So if I understood your post correctly, I need to get rid of the high_end and low_end parts in the mb-header and the linker file, right?
Re: How to avoid or compensate moved entry points
Posted: Fri Jun 08, 2012 6:10 am
by Combuster
Personally, GRUB2 is tagged as "unreliable", with repeated mentions of not adhering to its own specification across the forum, although several of them have been fixed since. What you mentioned to try is for instance not in the version of standard google puts on top. So I'm basically hoping someone (or google) has a known working solution.
I would start with telling the linker to emit a flat binary with all the gaps in place instead of ELF for that being the safest solution. You could then even replace the header and magic numbers and it would work with grub legacy as well.