problem linking modules

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.
Post Reply
alex_spain
Posts: 8
Joined: Tue Jun 19, 2007 10:32 am

problem linking modules

Post by alex_spain »

Well... my problem comes out when I try to link together two modules into one flat binary file. It's just a test, that consists in just a main module that calls an external name from the other. This second one prints in the screen a string.
When this printing module is compiled alone, it works perfectly, but when I try to link it whith the other one, it crashes.
I need the code to start in a specific location, in order to load it from the bootsector. For this purpose I use the BootF2, from John Fine.
I use nasm to compile the files, and LD to link them.

I'd thank a lot any answer, as I'm a newbe, and probably this is a stupid mistake.
User avatar
Combuster
Member
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:

Post by Combuster »

Could you please post your sources and linker script for reference?
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
alex_spain
Posts: 8
Joined: Tue Jun 19, 2007 10:32 am

Post by alex_spain »

The main function is:

BITS 32



global inicio

inicio:

mov edi, 0xB8000
mov esi, message
mov ah, 6 ;Text attribute
.again: lodsb
stosw
test al, al
jnz .again

ret



And the loader source is:

BITS 32


extern inicio


global loader

loader:
call inicio
jmp $ ; halt


Finally, my linker script is:

OUTPUT_FORMAT("binary")

SECTIONS
{
. = 0x0FF800000;
ENTRY(loader)
.text 0xFF800000 : {
*(.text)
}
.data : {
*(.data)
}
.bss :
{
*(.bss)
}
}


I hope this can let you give me some help.
User avatar
Combuster
Member
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:

Post by Combuster »

It seems that the bootloader forces entry to a hardcoded address, namely the start of the binary. LD doesn't know that and puts a different file at the start without bothering about the potentially hazardous effects that come with it.

What (likely) happens, is that execution is started at inicio: which puts a string on the screen, then tries to return. However, there is nothing to return to. The net result is a system crash. Depending on your version of ld changing the order of input files might or might not solve that. If it doesn't, search the forum as several solutions have been proposed in the past of which I don't know the details. You can disassemble the output to see wether the result is as expected.

The other problem you might be having is because you haven't set up a stack, which might cause a page fault when doing calls. To fix that you have to reserve space for it:

Code: Select all

LEA ESP, [stackend]

...

stack: TIMES 4096 DB 0
stackend:
Good luck with your endeavours.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
alex_spain
Posts: 8
Joined: Tue Jun 19, 2007 10:32 am

Post by alex_spain »

Thank you very much for the reply.
I've tried both fixes, I've set up a stack, and I've changed the order of the files. I also tried to force the called function to hang just before it has to return, to check whether it's failing there. It's still rebooting continously.
jnc100
Member
Member
Posts: 775
Joined: Mon Apr 09, 2007 12:10 pm
Location: London, UK
Contact:

Post by jnc100 »

alex spain wrote:

Code: Select all

 .text 0xFF800000 
Out of interest, why are you linking to that address? I presume you're not loading it there. Any absolute jumps/calls will try and jump somewhere just below 4GB. Unless you have 4GB of physical memory, of course...

Regards,
John.
alex_spain
Posts: 8
Joined: Tue Jun 19, 2007 10:32 am

Post by alex_spain »

The reason to use that address is because the bootloader, which isn't mine, tries to load in that address. I don't know exactly why, but it's what it does.
When I use that addres, but whith an ORG instruction in a flat binary file, it works fine. But, of course, I'm not going to program everything into one huge file, just because I have problems to link, xD
jnc100
Member
Member
Posts: 775
Joined: Mon Apr 09, 2007 12:10 pm
Location: London, UK
Contact:

Post by jnc100 »

Yes, I see now. BootF2 enables paging and maps the kernel to 0xff800000. Perhaps you could post a disk image?

Regards,
John.
User avatar
Kevin McGuire
Member
Member
Posts: 843
Joined: Tue Nov 09, 2004 12:00 am
Location: United States
Contact:

Post by Kevin McGuire »

alex_spain wrote:Thank you very much for the reply.
I've tried both fixes, I've set up a stack, and I've changed the order of the files. I also tried to force the called function to hang just before it has to return, to check whether it's failing there. It's still rebooting continously.
Did you try to hang it right before it starts executing with:

loader:
jmp loader


If it still reboots?
alex_spain
Posts: 8
Joined: Tue Jun 19, 2007 10:32 am

Post by alex_spain »

Yes, it's still rebooting, so I expect the problem is the entry point to the module, not the code itself. Thank you for this detail, now i know better where the problem is.
User avatar
Combuster
Member
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:

Post by Combuster »

Well since debugging is not much different than verifying assumptions, I suggest you do both of the following (in any order):

1) Get Bochs. It saves you from having to walk across the room with your floppy disk, and it allows you to get precise information on what goes awry. Have it run your kernel and it will tell you everything that happens when your code crashes. You can use the debugger version to see what code is actually being executed at what point

2) Some ld's don't allow for the order of files to be suggested on the command line. Have you indeed used a disassembler to be sure that the right code comes up first?
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
alex_spain
Posts: 8
Joined: Tue Jun 19, 2007 10:32 am

Post by alex_spain »

Thanks. I'm using Bochs since the beggining, and it's working fine. I'll probably try to use as linker JLOC, because I've seen that the LD that comes with DJGPP has lots of problems. I dissassembled the final code, and it has a huge amount of rubbish, where I couldn't localise my code. This means that the linker isn't doing what it has to, so, as I said, will try to use another one.
Excuse me for my lack of experience, and thank all you for your information.
User avatar
Combuster
Member
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:

Post by Combuster »

I just tried building it with my own toolchain and the only thing I found was that "message" was missing.

after adding

Code: Select all

message db "test", 0
I could assemble and link everything normally and the result was as expected.
Thanks. I'm using Bochs since the beggining, and it's working fine.
Next time, would you please post a complete and accurate error description, since in your first post you suggested it always crashed, while it apparently works fine in bochs... That makes the range of potential solutions radically different.

Now, I built everything as follows:
yasm -f elf -o alex_1.o alex_1.asm
yasm -f elf -o alex_2.o alex_2.asm
i386-elf-ld -T alex.ld alex_1.o alex_2.o -o alex.bin
and it gave the expected output.

Would you for now please provide:
- ALL of your CURRENT sources, complete, and with filenames (and please use [ code ] tags, rather than colors)
- the command lines you use to build them
- any other things you may have tried that we do not know anything about, more detailed descriptions of the error, including things you can make up out of the disassembly. Even the output size is useful.

And while (imho preferrably before) you wait for the answer:
- Build a GCC Cross-Compiler and use that
- Try the sequence above, and try providing all the command-line switches needed to prevent os-dependent code from being linked in.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
alex_spain
Posts: 8
Joined: Tue Jun 19, 2007 10:32 am

Post by alex_spain »

Thank you very much for the information. From now on I will make things as you say. I'm a newbe, and don't know exactly what should be necessary.
Post Reply