Page 1 of 1
i386 architecture of input file is incompatible with output
Posted: Fri Jan 21, 2011 5:00 pm
by Jacic
Hi, Ive been wanting to start simple OS development, and recently found this tutorial:
http://www.jamesmolloy.co.uk/tutorial_html/index.html. I got up to the point in chapter 2 where he says to compile, and I get this output from make:
Code: Select all
>make
ld -Tlink.ld -o kernel boot.o main.o
ld: i386 architecture of input file `boot.o' is incompatible with i386:x86-64 output
make: *** [link] Error 1
Im on a 64-bit machine, with this OS:
OS: Linux 2.6.31.14-0.4-desktop x86_64
System: openSUSE 11.2 (x86_64)
I tried adding the '-m64' flag in CFLAGS and LDFLAGS in my makefile, neither of which worked. Id be very grateful if someone could help me get this to work. Thanks.
Re: i386 architecture of input file is incompatible with out
Posted: Fri Jan 21, 2011 8:11 pm
by Tosi
Have you checked the Wiki, as this is a common problem so the answers are probably there.
I would suggest you build a
cross compiler that supports an i386-elf target.
You could also look at the binutils manual for information on emulation options in LD and objcopy.
Re: i386 architecture of input file is incompatible with out
Posted: Sat Jan 22, 2011 8:19 am
by Graham
You could try adding -melf_i386 to the flags you pass to ld and -m32 to the flags you pass to the C compiler. I do this on my 64 bit pc with ld and gcc from the Ubuntu repository and it works fine.
You wouldn't want to pass -m64 since JamesM's tutorial is solely about making a 32-bit protected mode operating system and as such you need to be producing 32-bit code, not 64-bit code

.
Re: i386 architecture of input file is incompatible with out
Posted: Tue Jan 25, 2011 2:43 am
by JamesM
Graham wrote:You could try adding -melf_i386 to the flags you pass to ld and -m32 to the flags you pass to the C compiler. I do this on my 64 bit pc with ld and gcc from the Ubuntu repository and it works fine.
You wouldn't want to pass -m64 since JamesM's tutorial is solely about making a 32-bit protected mode operating system and as such you need to be producing 32-bit code, not 64-bit code

.
That is exactly the solution.
Re: i386 architecture of input file is incompatible with out
Posted: Tue Jan 25, 2011 5:00 pm
by Jacic
JamesM wrote:Graham wrote:You could try adding -melf_i386 to the flags you pass to ld and -m32 to the flags you pass to the C compiler. I do this on my 64 bit pc with ld and gcc from the Ubuntu repository and it works fine.
You wouldn't want to pass -m64 since JamesM's tutorial is solely about making a 32-bit protected mode operating system and as such you need to be producing 32-bit code, not 64-bit code

.
That is exactly the solution.
Thanks for the help everyone, but when I make the above changes, Im given the original error, except talking about main.o instead of boot.o

Re: i386 architecture of input file is incompatible with out
Posted: Wed Jan 26, 2011 3:06 pm
by Tosi
I would still recommend making a cross compiler.
I know your system probably comes with gcc, and you can tweak the flags to get it to work for OS dev, but making a cross compiler
will solve so many problems. It also serves as a kind of test to see if you meet some of the requirements for OS development.
If you don't want to make a cross compiler though, you can look at the manuals for your compiler to find the right flags to pass.
Look up "emulation" options or something similar.
GCC Manuals
Documentation for binutils 2.20 (you will most likely want LD documentation)
Re: i386 architecture of input file is incompatible with out
Posted: Thu Jan 27, 2011 4:14 pm
by Jacic
I took tosi's advice (I think thats who first suggested it) and built a cross compiler following the wiki instructions. However, Im unclear as to how to specify my cross compiler in the makefile instead of my regular gcc setup. Could someone please help me with this?
My Makefile:
Code: Select all
SOURCES=boot.o main.o
CFLAGS=-nostdlib -nostdinc -fno-builtin -fno-stack-protector
LDFLAGS=-Tlink.ld
ASFLAGS=-felf
all: $(SOURCES) link
clean:
-rm *.o kernel
link:
ld $(LDFLAGS) -o kernel $(SOURCES)
.s.o:
nasm $(ASFLAGS) $<
Re: i386 architecture of input file is incompatible with out
Posted: Thu Jan 27, 2011 4:33 pm
by Tosi
It depends on where you installed your cross-compiler. I used the prefix /home/my_username/opt since that is where I install things I compiled without using portage (it makes it easy to remove). So I just added this to my path,
making sure that I don't mess up my host compiler and compiled and installed there.
If the path to the compiler is not in your system's $PATH, I recommend adding it.
My Makefile has almost these exact lines in it:
Code: Select all
TARGET := i586-elf
CC := $(TARGET)-gcc
LD := $(TARGET)-ld
$(TARGET) is the CPU and executable format you intend to use. GCC and binutils by default compiler their programs to TARGET_PREFIX-TOOL_NAME, so this won't mess up your system's compiler which is most likely just invoked by "gcc."
Once you have the compiler set up, add some rules in your Makefile to compile. Here is a simplified version of the rule I use to compile plain C files:
Now, since you have compiled for the system you intend to target, you don't have to mess with emulation flags and PE operations and all that.
Re: i386 architecture of input file is incompatible with out
Posted: Thu Jan 27, 2011 5:02 pm
by Jacic
Ok, I modified my makefile so it looks like this:
Code: Select all
SOURCES=boot.o main.o
CFLAGS=i386-elf-gcc -nostdlib -nostdinc -fno-builtin -fno-stack-protector
LDFLAGS=-Tlink.ld
ASFLAGS=-felf
all: $(SOURCES) link
clean:
-rm *.o kernel
link:
i386-elf-ld $(LDFLAGS) -o kernel $(SOURCES)
.s.o:
nasm $(ASFLAGS) $<
Now I get this whenever i try to compile:
i386-elf-ld -Tlink.ld -o kernel boot.o main.o
main.o: file not recognized: File format not recognized
Sorry if this all sounds noobish, its been awhile since I did anything with makefiles.
Re: i386 architecture of input file is incompatible with out
Posted: Thu Jan 27, 2011 7:57 pm
by Tosi
Code: Select all
CFLAGS=i386-elf-gcc -nostdlib -nostdinc -fno-builtin -fno-stack-protector
You are including the compiler's name in the $(CFLAGS) variable. Also since you didn't set $(CC) it's invoking your host compiler by default, which is configured for something like an x86_64-elf-pc. Break the $(CFLAGS) definition up into
Code: Select all
CC=i386-elf-gcc
CFLAGS=-fno-builtin -fno-stack-protector
Since you are now using a cross-compiler, you don't need the flags "-nostdlib -nostdinc" since it knows of no stdlib or include files to bring in.
Also, I would recommend adding some CFLAGS. The ones I recommend the most are "-Wall -Werror -Wextra -pedantic" at least. If you haven't used them much you will probably get tons of errors, but it has helped me catch some nasty bugs I could have otherwise avoided. Also, "-fno-builtin -fno-stack-protector" will only turn on those 2 special optimizations. If you want most of the optimizations that are safe, use "-O2". I wouldn't recommend going anything over that, especially for OS development.
One other thing is missing from the Makefile, though it isn't absolutely necessary if you set the variables. You have no explicit rules for compiling C sources. If you need an example of such a rule, I wrote a simple one in my previous post. It doesn't do anything special with dependencies though.
Re: i386 architecture of input file is incompatible with out
Posted: Thu Jan 27, 2011 8:33 pm
by Jacic
>.< I should have realized that. Anyway, thanks a ton for the great help!