linking asm and c with ld

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
IRBMe

linking asm and c with ld

Post by IRBMe »

Thanks to the wonderful help I recieved here, I now have a working boot sector, and loader and can successfuly get into protected mode, which is a big step considering I only just started looking into OS developement properly a few days ago.

But enough with the rambling. I face another (incredibly newbish) problem with using ld.

Firstly, I have this code, which is jumped to by the loader right after entering protected mode, kernel.asm:

Code: Select all

[bits 32]

extern _c_main
   
   ; Jump into the main kernel
   call _c_main

   ; Halt the CPU
   cli
   hlt
Now, here is the C code, kernel_c.c:

Code: Select all

char message[]= "C Kernel loaded.";

int c_main () 
{

   char *source = message;
   char *destination = (char *)0xB8000;

   while (*source) 
   {
      *destination++ = *source++;
      *destination++ = 7; 
   }
   
   return 0;
}
Simple enough, yes?
Now my problem is trying to compile the thing.

First I assemble the kernel.asm file to an object file:

Code: Select all

nasm -f coff kernel.asm -o kernel.o
Then I try to compile the C code to an object file:

Code: Select all

gcc -O3 -c kernel_c.c -o kernel_c.o
Now I try to link them:

Code: Select all

ld -Ttext 0xFF800000 --oformat binary -o kernel.bin kernel.o kernel_c.o
I copied this from an example. Just as a "side" question. What exactly does "0xFF800000" do? Do I replace this with the location I loaded my kernel.asm file to (DATA_SEL:0x2000) or does this number not particularly matter? (I have the A20 line enabled, and am in P-Mode with a flat data and code segment but don't have paging turned on [YET!], if any of that's relevant)

Anyway now the main problem. I can get so far as having 2 object files, but they won't link. I get this error:

"ld: PE operations on non PE file."

I read somewhere that this was a problem with a certain version of ld, so I tried a few other versions. Other versions just gave the same thing, or actually caused a general protection fault and crashed ("ld has encountered a problem and needs to close").

I also read somewhere to try "aout" instead of "coff", but then ld complained about unknown file formats, so back to "coff" i went.

I'm guessing it's something pretty newbish I'm doing, but I've searched all over the web, read the documentation, and read other examples, and I just can't see what's wrong.

(As a side note, I'd rather do things simply from the command line like this, than use a linker script, if that can be avoided)

Thanks in advance.
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:linking asm and c with ld

Post by Pype.Clicker »

IRBMe wrote: I copied this from an example. Just as a "side" question. What exactly does "0xFF800000" do?
It tells the linker that you'd like the very first byte of the object to be at offset 0xFF800000 in the segment. You'll notice that this is probably out of the physical memory and thus requires you to set up memory mapping unit (either paging or segmentation) accordingly so that it works ...

Anyway now the main problem. I can get so far as having 2 object files, but they won't link. I get this error:

"ld: PE operations on non PE file."

I also read somewhere to try "aout" instead of "coff", but then ld complained about unknown file formats, so back to "coff" i went.
That's a common issue, indeed. Probably the best for you is to switch to another development environment (cygwin ?). As an alternative, you may try to link to a "normal" executable (ignoring --oformat binary and stuff like this) and *then* use a tool like objcopy (in gnu/binutils) to translate to a binary file.
IRBMe

Re:linking asm and c with ld

Post by IRBMe »

It tells the linker that you'd like the very first byte of the object to be at offset 0xFF800000 in the segment. You'll notice that this is probably out of the physical memory and thus requires you to set up memory mapping unit (either paging or segmentation) accordingly so that it works ...
Would I replace 0xFF800000 with the address my kernel is loaded to (0x2000)? Actually, is 0x2000 a good location at all? I just chose it because it's after my loader (which is loaded right after the boot sector) and still allows my loader plenty of space to grow.
Probably the best for you is to switch to another development environment (cygwin ?).
That's not really a practical option for me at the moment. My developement environment is a Win XP box, and I'm stuck with that.

I also have JLOC, ML and LINK tools, if they would be any good? Any idea how to use either of them to do what I want, if anybody knows off the top of their head?
User avatar
df
Member
Member
Posts: 1076
Joined: Fri Oct 22, 2004 11:00 pm
Contact:

Re:linking asm and c with ld

Post by df »

cygwin runs inside XP.
basically you run the cygwin setup.exe and it downloads the base, you can tell it to download gcc.

its the recommended setup for OSDev on WinXP :)

http://www.cygwin.com/setup.exe

or check out http://www.cygwin.com
-- Stu --
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:linking asm and c with ld

Post by Pype.Clicker »

IRBMe wrote: Would I replace 0xFF800000 with the address my kernel is loaded to (0x2000)? Actually, is 0x2000 a good location at all? I just chose it because it's after my loader (which is loaded right after the boot sector) and still allows my loader plenty of space to grow.
yes. i'd do it this way... However, i'd use something *above* 0x7C00 so that a growing kernel doesn't overwrite the loader. 0x10000 (ES=0x1000, BX=0) seems a nice option.

Chances that your kernel gets over 512K or that you need more than 64K for a V8086 task are virtually null ...
IRBMe

Re:linking asm and c with ld

Post by IRBMe »

Well thanks alot for the replies guys. I'm currently downloading and installing cygwin at your recomendation, but I managed to get it to work by reinstalling DJGPP. Also I did some proper background reading on the --tText switch and figured out how I should do it, and it's all working perfectly now.

And cygwin should be done fairly soon :)
Post Reply