How do I use a cross compiler?
How do I use a cross compiler?
Hello, I've finally decided to use a cross-compiler for development, and because of the fact that I needed to mix 16 and 32-bit code for my second-stage bootloader (along with other reasons), I compiled binutils and gcc to target i386-aout. Now that's not the problem; everything built correctly there. I'm just wondering now that I've got my toolchain compiled, how do I use it? I've gotten everything working from the command line and batch files (using cygwin1.dll), but gcc doesn't output anything when I try to compile source files (regardless of flags; even "gcc -o main.o main.c" doesn't give me anything).
Where am I going wrong? Do my source files need to have Unix-style carriage returns? Do I need to run gcc from bash or sh? Sorry if I sound lost, I'm just used to my old tools (djgpp) working, and these new ones (gcc-i386-aout) not doing the same has sort of thrown me off. Any help would be appreciated.
Where am I going wrong? Do my source files need to have Unix-style carriage returns? Do I need to run gcc from bash or sh? Sorry if I sound lost, I'm just used to my old tools (djgpp) working, and these new ones (gcc-i386-aout) not doing the same has sort of thrown me off. Any help would be appreciated.
- Combuster
- 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:
I have the cygwin bin path in my system path. The only significant difference is that you use the run dialog/windows command prompt, with the different syntax from bash.Not sure if they work that well otherwise.
The good thing is that I don't have to bother about making the distinction between ls and dir anymore
Well, I've found what my problem is. I ran gcc (cross compiler) from bash in cygwin, and it gives me this error:
Now, I've looked around, and apparently this has something to do with libc, which is weird, since I'm not using a libc for my kernel and I didn't enable using one (unless such a thing is enabled by default) in my options when I built gcc. I'm not from a Unix background, as you can probably tell, so could anyone tell me if I'm missing anything obvious or, if it's not an obvious problem, could anyone point me in the right direction?
Also, in case this was important, I followed the cross compiler tutorial on the wiki word-for-word, aside from targetting i386-aout instead of i586-elf.
Code: Select all
/usr/cross/lib/gcc/i386-aout/3.4.3/../../../../i386-aout/bin/ld: cannot find -lc
Also, in case this was important, I followed the cross compiler tutorial on the wiki word-for-word, aside from targetting i386-aout instead of i586-elf.
It is. Look at the Bare bones tutorial for a "known good" set of compiler options.lollynoob wrote:...I'm not using a libc for my kernel and I didn't enable using one (unless such a thing is enabled by default)...
Every good solution is obvious once you've found it.
Well, I just tried using the flags the bare-bones tutorial suggests I do (-nostdlib -nostartfiles -nodefaultlibs), and I get this error. Pardon me for throwing error codes out there for people to fix, but I'm not really sure how to resolve this problem.
As far as my code goes, it's just a simple main() with code to put an 'A' into the first character of the text mode buffer.
Edit: I'm not sure I understand why (I'll look it up), but using "gcc -o main.o -c main.c" (as the bare-bones tutorial did) worked, whereas my old "gcc -o main.o main.c" did not. Thanks for the help, everyone.
Code: Select all
cczKLNk2.o:(.text+0x1d): undefined reference to `___main'
Edit: I'm not sure I understand why (I'll look it up), but using "gcc -o main.o -c main.c" (as the bare-bones tutorial did) worked, whereas my old "gcc -o main.o main.c" did not. Thanks for the help, everyone.
Thats because the first method doesn't invoke the linker, and what you're getting is a linker error.Edit: I'm not sure I understand why (I'll look it up), but using "gcc -o main.o -c main.c" (as the bare-bones tutorial did) worked, whereas my old "gcc -o main.o main.c" did not. Thanks for the help, everyone.
Some compilers add "_" characters to the front of every C symbol. If you're calling C code from ASM, watch out for that. You may have to prepend a "_" yourself so the correct symbol is called.
Well, I've got my main.c to compile to cmain.o (a.out) and my 16-bit assembly code to compile to amain.o (a.out), but now when I try to link the two to a single binary, I get this error:
If this is a simple problem, could someone point me in the right direction to solve it? Also, if more information is needed (my code, build script, makefile, or linker script, for example), I can post anything related that's important.
Thanks for helping.
Edit: I've decided that instead of messing with mixing 16 and 32-bit code in one binary, I'll just concatenate my 32-bit binary to the end of my 16-bit one. This should work more smoothly than making an ugly mix when I don't need to.
Code: Select all
bin/cmain.o:bin/cmain.o:(.text+0x1d): undefined reference to `___main'
Thanks for helping.
Edit: I've decided that instead of messing with mixing 16 and 32-bit code in one binary, I'll just concatenate my 32-bit binary to the end of my 16-bit one. This should work more smoothly than making an ugly mix when I don't need to.
Hint #1: main() is the entry point for a userspace application. If your kernel binary contains any references to main(), some part of your toolchain tries to build a userspace binary.
Hint #2: To avoid confusion, do not call your kernel's entry point main(). Use kmain(), kstart() or similar. This makes error messages more helpful.
Hint #3: Make sure your Assembler and your Compiler agree on the "underscore rule" (whether to prefix a function name with an underscore or not). Personally I prefer toolchains that do not add underscores, because it's the kind of implicit, unexplained behaviour that gives you headaches. Create a dummy .asm and .c file containing one function only, and use objdump to check which "underscore rule" is applied by your respective tools.
Hint #4: Do this kind of learning about your toolchain in userspace if at all possible.
Hint #2: To avoid confusion, do not call your kernel's entry point main(). Use kmain(), kstart() or similar. This makes error messages more helpful.
Hint #3: Make sure your Assembler and your Compiler agree on the "underscore rule" (whether to prefix a function name with an underscore or not). Personally I prefer toolchains that do not add underscores, because it's the kind of implicit, unexplained behaviour that gives you headaches. Create a dummy .asm and .c file containing one function only, and use objdump to check which "underscore rule" is applied by your respective tools.
Hint #4: Do this kind of learning about your toolchain in userspace if at all possible.
Every good solution is obvious once you've found it.