Page 1 of 1

help on linking a 32 bit OS in a 64bit environment

Posted: Thu Jul 26, 2007 2:17 am
by kenneth_phough
I'm trying to link the kernel entry (written in asm) and the kernel (written in C) however I get the following warning:

Code: Select all

ld: warning: i386 architecture of input file 'semi.o' is incompatible with i386:x86_64 output
The warning doesn't sound good but I still get a linked binary kernel.bin file. I think the linked file is fine; I haven't tested it because my home made boot loader doesn't seem to like it. It executes the code but prints random text, not the stuff I specified in the data section. I think I know how to solve this problem. I found a article in the forum on a similar issue. However, my primary concern is this warning. Is this warning something I should be concerned about and if so how could I tell ld to output i386 binary?

Yours,
Kenneth

Posted: Thu Jul 26, 2007 2:42 am
by JamesM
I'll repost later this afternoon when I get home and can check my linker script (I compiled 32-bit in a 64-bit environment before I reinstalled linux).

It's pretty much the same flag as GCC -

Code: Select all

ld -m elf_i386
In gcc it's just -m32.

This should work.

JamesM

Re: help on linking a 32 bit OS in a 64bit environment

Posted: Thu Jul 26, 2007 2:45 am
by urxae
I think these are your options:
1) put something like

Code: Select all

OUTPUT_FORMAT("elf32-i386")
(from the wiki) at the top of your linker script, or
2) pass -m<emu> to ld, where available <emu> options are in the first lines of the output of "ld --verbose". Mine has "elf_i386", but this may depend on ld version and compilation options.

For normal programs, there's also
3) pass -m32 to gcc when linking
but for an OS you're probably using ld directly.

All of these specify ld's output format as

Posted: Thu Jul 26, 2007 3:24 am
by kenneth_phough
Thanks guys :D
I think that solved the problem! However, now there is another problem, which I thought I knew the answer to.
My boot loader loads all 10 cylinders of the floppy onto memory starting at 0x7e00. Doing an objdump of my floppy I found that my second stage loader (i guess it's more like a kernel_entry) starts from 0x04400. Everytime I re-format my floppy and copy a file, the first file that is coppied to an empty floppy is saved in 0x04400 an on. So I reasoned that that is where it was going to be, thus after reading the floppy into mem, I just had to jump to 0x7e00+(0x04400-0x200) [subtract the 512 of the boot sector from the 0x04400 because everything but the 1st sector is read into mem] to execute the second stage boot loader. This was fine while my second stage boot loader was just 1 asm file. However, when I started writing the kernel in C and linked it to the second stage boot loader, things went all wrong. I did several binary dumps of my floppy and found out how to get to the code of my second stage boot loader( i think it was something like [linked phys address] + [0x4400] - [0x200]). So I rewrote my boot sector and tried running my "os" and found out that the code was executed but the strings that I wanted to have printed out onto the screen didn't get printed. Instead I got weird characters (S = S=):

Code: Select all

Initializing system for Natzu...S = S=
I finally came to the conclusion that I am linking my object files wrong, however I am not sure of the exact problem, so I can figure out how to fix it. I read an article on a similar issue but that didn't help. Does anyone know what the problem is and how to fix it? Thanks.

Yours,
Kenneth

Posted: Thu Jul 26, 2007 3:40 am
by urxae
Sounds like the address you load your kernel and the address your linker thinks it will get loaded at are different. Add "-Ttext <address>" to your ld command line or modify your linker script to link at the right address.

Posted: Thu Jul 26, 2007 5:40 am
by kenneth_phough
Thanks! That was simple wasn't it. Sorry for my stupidity. :oops:
because I was jumping to 0xC00 I just had to change the ld script to link the kernel at 0xC00.

Yours,
Kenneth