Page 1 of 3

How to use cross-compiler on Brian Tutorial

Posted: Sat Jun 17, 2006 7:45 am
by jason7007
Hi,

I successfully made the cross-compiler using the tutorial in faq.
I want to test this cross-compiler on Brian Kernel development tutorial. Is the batch file in Brian tutorial applicable to my cross-compiler, or do we have to change the syntax, especially the options. Or I should say what is the equivalent of build.bat file in Brian tutorial to my cross-compiler in Cygwin? Can I make script file and then type name of script file as command line? Sorry I am not Unix/Linux guy, I don't know about batch file in Unix/Linux.

Here is the build file in Brian Tutorial

Code: Select all

echo Now assembling, compiling, and linking your kernel:
nasmw -f aout -o start.o start.asm
gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o main.o main.c 
gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o str.o str.c 
gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o mem.o mem.c
gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o port.o port.c
gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o scrn.o scrn.c
gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o gdt.o gdt.c
gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o idt.o idt.c
gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o isrs.o isrs.c
gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o irq.o irq.c
gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o timer.o timer.c
gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o kb.o kb.c
Can someone please guide me on how to do this?

Your help will be appreciated.
Thanks.

Re:How to use cross-compiler on Brian Tutorial

Posted: Sat Jun 17, 2006 9:55 am
by Warrior
Well (using cygwin) your cross compiler is located in another directory. You'll need to edit your enviroment variables to poit to the cross GCC. The OSFaq shows how to do this although for a more permanent solution I just made it set the env var in a startup script.

Same would apply for ld, nasm, etc.. (Not sure if all of these need to be made cross compiled)

Re:How to use cross-compiler on Brian Tutorial

Posted: Sat Jun 17, 2006 12:59 pm
by jason7007
Hi,

I wonder if we still need to put those so many options since this is a cross-compiler. Any actual sample?



Thank so much.

Re:How to use cross-compiler on Brian Tutorial

Posted: Sat Jun 17, 2006 2:36 pm
by Bob the Avenger
I haven't built a cross-compiler yet, thats on my todo list after failing my exams, i would suggest keeping them in

"-Wall -O -fstrength-reduce -fomit-frame-pointer -finline" functions i would keep in definitely

you could try a compile without "-nostdinc -fno-builtin" and see how ld reacts

Re:How to use cross-compiler on Brian Tutorial

Posted: Sat Jun 17, 2006 7:24 pm
by Midas
In terms of command-line options, here's what I use (excerpt from my Makefile):

[tt]# Set our CC flags
#   Wall      - Enable all warnings
#   Werror      - Exit at first error
#   pedantic   - Warn verbosely
#   pedantic-errors   - Generate errors where pedantic would generate a warning
#   nostdlib   - No C standard stuff (library, runtime etc)
#   nostartfiles   - With above
#   nodefaultlibs   - With above
#   fno-leading-underscore   - Symbols like 'main', not '_main'
#   ffreestanding   - We're freestanding - eliminates some irrelevant
#          warnings and errors, etc
#   std=gnu99   - I'm used to C99 compliant code, but need GCC some of
#          the GCC extensions (like inline ASM)
#   -I./include   - Add our header-include directory
# Some of these may seem irritating, but the code is better for it[/tt]

Also note that the -fno-underscores is unnecessary and is only there for compatibility. I've not come across any problems with this - and can't think of any. They won't give you very /optimised/ code, but I feel that's better for manually tracing through the code.

Re:How to use cross-compiler on Brian Tutorial

Posted: Sat Jun 17, 2006 11:44 pm
by Candamir
Actually, Bran's Kernel Development Tutorial does use leading underscores, so you either remove all leading underscores in ASM or remove that options. Anyhow, my cross-compiler doesn't put leading underscores in front of C declarations by default, so maybe that's also the case with the one you built, but you'll notice that anyway soon enough as the linker's going to complain about it.

BTW: If you followed all the steps, you'll also have what I call "cross-binutils", including ld. NASM doesn't need to be cross-compiled, just download the newest package with setup.exe (you work with Cygwin, do you?).

As you asked for a sample, here's what I got:

Code: Select all

# This includes the default (the one from the FAQ) crosscompiler path
export PATH=$PATH:/usr/cross/bin

# NASM example
nasm -f elf -o start.o start.asm

#GCC example (these are my options, dunno if they're correct, but they work ;) )
i386-elf-gcc -Wall -Werror -O3 -fno-builtin -I./include -c -o main.o main.c

# LD (I put /everything/ in my linker script, input files, output file/format, etc.)
# I hope you got your linker script, if not, I'd head for some of the BareBones tutorials in the Wiki
# The ld manual is also a must if you want to do more advanced stuff with your linker
i386-elf-ld -T link.ld

#I think bkerndev has something like this
rm *.o

# You can add many more things, such as copying your kernel to the floppy drive, start Bochs, etc.
Actually, bkerndev proposes a batch file, but as these work only in Windows, you should create a sh script, like build.sh and invoke it like that ./build.sh (from the same directory). If you know how to, you could also write a makefile instead of a sh script, but I'll leave that to somebody else to explain ;)

Hope this helps

Candamir

Re:How to use cross-compiler on Brian Tutorial

Posted: Sun Jun 18, 2006 10:15 pm
by jason7007
Hi

Why I am getting this error from the linker?

start.o : file not recognized: File format not recognized

This is the build file.

echo Now assembling, compiling, and linking your kernel:
nasmw -f aout -o start.o start.asm
rem Remember this spot here: We will add 'i386-elf-gcc' commands here to compile C sources

i386-elf-gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o main.o main.c

i386-elf-gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o scrn.o scrn.c

i386-elf-gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o gdt.o gdt.c

i386-elf-gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o idt.o idt.c

i386-elf-gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o isrs.o isrs.c

i386-elf-gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o irq.o irq.c

i386-elf-gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o timer.o timer.c

i386-elf-gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o kb.o kb.c

rem This links all your files. Remember that as you add *.o files, you need to
rem add them after start.o. If you don't add them at all, they won't be in your kernel!
ld -T link.ld -o kernel.bin start.o main.o scrn.o gdt.o idt.o isrs.o irq.o timer.o kb.o
echo Cleaning up object files...
rem del *.o
echo Done!
pause

Any help would be appreciated.

Re:How to use cross-compiler on Brian Tutorial

Posted: Sun Jun 18, 2006 11:16 pm
by guest
nasmw -f aout -o start.o start.asm

Code: Select all

nasmw -f elf -o start.o start.asm

Re:How to use cross-compiler on Brian Tutorial

Posted: Sun Jun 18, 2006 11:17 pm
by Candamir
In your NASM commands, you still use "-f aout", but it must be "-f elf".

Your linker command must be "i386-elf-ld" instead of just "ld".

Try to do what I said right now, it should work unless you messed something up with your linker script... In order to actually produce an elf file with Bran's linker script, you had to change the output format command to OUTPUT_FORMAT("i386-elf") and delete everything starting at the line "phys = 0x00100000;" and then paste this (from BareBones in the FAQ, I'd highly recommend you to take a look at it - http://www.mega-tokyo.com/osfaq - the FAQ is probably one of the osdever community's most valuable resources, alongside with this very forum </speech>):

Code: Select all

SECTIONS
{
    . = 0x00100000;

    .text :
    {
        *(.text)
    }

    .rodata ALIGN (0x1000) :
    {
        *(.rodata)
    }

    .data ALIGN (0x1000) :
    {
        *(.data)
    }

    .bss :
    {
        _sbss = .;
        *(COMMON)
        *(.bss)
        _ebss = .;
    }
}
That should pretty much do it, now you should have Bran's kernel in ELF format.

Candamir

PS: I've done pretty much everything concerning the build process for you, so make sure you understand me, I'd also recommend you the ld manual as it will come in handy later when you're developing a higher-half kernel or trying to figure out where your kernel ends...

Re:How to use cross-compiler on Brian Tutorial

Posted: Mon Jun 19, 2006 12:09 am
by Solar
Candamir wrote: If you know how to, you could also write a makefile instead of a sh script, but I'll leave that to somebody else to explain ;)
"make" is one of those tools where you could know the manual by heart and still don't know what to do, and where dozens of ways exist in which to do things. Thus, the below is merely a "simple" example. In my experience it's easier to take the manual for understanding an existing makefile than it is to write one yourself...

Replace leading 8 spaces with tabs and safe as "Makefile" to your project root directory. "make kernel.bin" rebuilds your kernel, "make clean" removes all temporary files. You can compile individual object files with "make xyz.o". Note that this makefile will compile and link all C and ASM source files in the project directory and its subdirectories. The main advantage of "make" over batch files is that "make" only recompiles those files that actually need recompiling, which can make a big difference on large projects.

The *.d file this makefile creates are for header dependency tracking. Just ignore them.

Code: Select all

# set the tools to be used
CC := i386-elf-gcc
LD := i386-elf-ld

# set the C compiler flags
CFLAGS :=  -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include

# Modify these to "catch" different sets of files
# All C sources
CFILES := $(shell find . -name "*\.c")
# All ASM sources
ASMFILES := $(shell find . -name "*\.asm")
# All sources, regardless language
SRCFILES := $(CFILES) $(ASMFILES)
# All object files contributing to kernel.bin
OBJFILES := $(patsubst %.c,%.o,$(SRCFILES))
# Header dependencies for C files
DEPFILES := $(patsubst %.c,%.d,$(CFILES))

# Necessary so that cleaning is done even if a file "clean" should exist
.PHONY: clean

# First "rule" in a makefile is the default one, so you could just "make" instead of "make kernel.bin".
kernel.bin: ${OBJFILES} link.ld
        @$(LD) -T link.ld -o kernel.bin ${OBJFILES}

# This doesn't throw error messages if files do not exist
clean:
        -@for file in $(OBJFILES) $(DEPFILES); do if [ -f $$file ]; then rm $$file; fi; done

# Including the header dependency files (which contain make rules autogenerated by GCC below)
-include $(DEPFILES)

%.o: %.asm
        @nasmw -f elf -o $@ $<

# The -M* options auto-generate the dependency options
%.o: %.c
        @$(CC) -MMD -MP -MT "$*.d" -c $< -o $@
Hope this helps.

Re:How to use cross-compiler on Brian Tutorial

Posted: Mon Jun 19, 2006 12:20 am
by Candamir
Just one word about the compiler options: I'd also use -Werror, as warnings are considered as errors in that case. This may seem annoying, but remember; "the compiler is your friend" (don't remember who on this board said that, so I don't know whom to pay the credit ;) )

* Candamir is seriously considering getting some sleep now...

Re:How to use cross-compiler on Brian Tutorial

Posted: Mon Jun 19, 2006 12:39 am
by Solar
Candamir wrote: This may seem annoying, but remember; "the compiler is your friend" (don't remember who on this board said that, so I don't know whom to pay the credit ;) )
One of those proverbs that probably must be marked "traditional". I personally got it from the Amiga coding style guide as written by Heinz Wrobel ages ago, but I'm pretty sure he just quoted it himself.

Well, -Werror is a good way to educate yourself into not ignoring any of the warnings the compiler spits. On the downside it terminates your "make" (unless you run make -k). Personally, I prefer to run without -Werror and apply the "accept no warnings" rule manually. ;)

More importantly, -Wall does not enable "all" warnings. There are many, many more options you could enable, which aren't in -Wall because they might result in "false positives", i.e. give warnings for valid code. Check the GCC manual for details.

Re:How to use cross-compiler on Brian Tutorial

Posted: Mon Jun 19, 2006 7:20 am
by jason7007
Hi,

Candamir, I followed your instructions but now I am getting this error from the linker.

i386-elf-ld: target i386-elf not found.

Thank you for your patience.

Re:How to use cross-compiler on Brian Tutorial

Posted: Mon Jun 19, 2006 9:47 am
by Candamir
Sorry, my fault. Actual command I have in my linker script is:

Code: Select all

OUTPUT_FORMAT(elf32-i386)
That should do the job. Just in case it doesn't, please post your entire linker script and your linker command line.

Candamir

BTW: Take a look at the post "Cross compiler on XP", which is also a hot topic right now. Maybe that could also help you.

Re:How to use cross-compiler on Brian Tutorial

Posted: Mon Jun 19, 2006 10:35 am
by jason7007
Hi,

I already changed the script and followed yours but I am getting too many error messages. How can I output these messages to a file, cause I could not cut and patse from cygwin to windows.


Thank you for your patience.