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

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
User avatar
kenneth_phough
Member
Member
Posts: 106
Joined: Sun Sep 18, 2005 11:00 pm
Location: Williamstown, MA; Worcester, MA; Yokohama, Japan
Contact:

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

Post 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
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post 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
urxae
Member
Member
Posts: 149
Joined: Sun Jul 30, 2006 8:16 am
Location: The Netherlands

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

Post 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
User avatar
kenneth_phough
Member
Member
Posts: 106
Joined: Sun Sep 18, 2005 11:00 pm
Location: Williamstown, MA; Worcester, MA; Yokohama, Japan
Contact:

Post 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
urxae
Member
Member
Posts: 149
Joined: Sun Jul 30, 2006 8:16 am
Location: The Netherlands

Post 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.
User avatar
kenneth_phough
Member
Member
Posts: 106
Joined: Sun Sep 18, 2005 11:00 pm
Location: Williamstown, MA; Worcester, MA; Yokohama, Japan
Contact:

Post 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
Post Reply