You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3.8 KiB

Concepts you may want to Google beforehand: cross-compiler

Goal: Create a development environment to build your kernel

If you're using a Mac, you will need to do this process right away. Otherwise, it could have waited for a few more lessons. Anyway, you will need a cross-compiler once we jump to developing in a higher language, that is, C. Read why

I'll be adapting the instructions at the OSDev wiki.

Required packages

First, install the required packages. On linux, use your package distribution. On a Mac, install brew if you didn't do it on lesson 00, and get those packages with brew install

  • gmp
  • mpfr
  • libmpc
  • gcc

Yes, we will need gcc to build our cross-compiled gcc, especially on a Mac where gcc has been deprecated for clang

Once installed, find where your packaged gcc is (remember, not clang) and export it. For example:

export CC=/usr/local/bin/gcc-4.9
export LD=/usr/local/bin/gcc-4.9

We will need to build binutils and a cross-compiled gcc, and we will put them into /usr/local/i386elfgcc, so let's export some paths now. Feel free to change them to your liking.

export PREFIX="/usr/local/i386elfgcc"
export TARGET=i386-elf
export PATH="$PREFIX/bin:$PATH"

binutils

Remember: always be careful before pasting walls of text from the internet. I recommend copying line by line.

mkdir /tmp/src
cd /tmp/src
curl -O http://ftp.gnu.org/gnu/binutils/binutils-2.24.tar.gz # If the link 404's, look for a more recent version
tar xf binutils-2.24.tar.gz
mkdir binutils-build
cd binutils-build
../binutils-2.24/configure --target=$TARGET --enable-interwork --enable-multilib --disable-nls --disable-werror --prefix=$PREFIX 2>&1 | tee configure.log
make all install 2>&1 | tee make.log

gcc

cd /tmp/src
curl -O https://ftp.gnu.org/gnu/gcc/gcc-4.9.1/gcc-4.9.1.tar.bz2
tar xf gcc-4.9.1.tar.bz2
mkdir gcc-build
cd gcc-build
../gcc-4.9.1/configure --target=$TARGET --prefix="$PREFIX" --disable-nls --disable-libssp --enable-languages=c --without-headers
make all-gcc 
make all-target-libgcc 
make install-gcc 
make install-target-libgcc 

That's it! You should have all the GNU binutils and the compiler at /usr/local/i386elfgcc/bin, prefixed by i386-elf- to avoid collisions with your system's compiler and binutils.

You may want to add the $PATH to your .bashrc. From now on, on this tutorial, we will explicitly use the prefixes when using the cross-compiled gcc.

how to compile the project with GCC V 10.2.0 in x64 environments

add CFLAGS & LDFLAGS in Makefile

CFLAGS =  -ffreestanding -fno-stack-protector -z execstack -m32 -no-pie -fno-pic 
LDFLAGS = -melf_i386

the Makefile in 14-17

C_SOURCES = $(wildcard kernel/*.c drivers/*.c)
HEADERS = $(wildcard kernel/*.h drivers/*.h)
# Nice syntax for file extension replacement
OBJ = ${C_SOURCES:.c=.o}


CC = gcc
GDB = gdb

CFLAGS =  -ffreestanding -fno-stack-protector -z execstack -m32 -no-pie -fno-pic 
LDFLAGS=  -melf_i386

os-image.bin: boot/bootsect.bin kernel.bin
	cat $^ > os-image.bin

kernel.bin: boot/kernel_entry.o ${OBJ}
	ld ${LDFLAGS} -o $@ -Ttext 0x1000 $^ --oformat binary

kernel.elf: boot/kernel_entry.o ${OBJ}
	ld ${LDFLAGS} -o $@ -Ttext 0x1000 $^

run: os-image.bin
	qemu-system-x86_64  -fda os-image.bin

debug: os-image.bin kernel.elf
	qemu-system-x86_64 -s -S -fda os-image.bin & 
	${GDB} -ex "target remote localhost:1234" -ex "symbol-file kernel.elf" -ex "break *0x7c00" -ex "break main" -ex "c" -ex "c" 

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

%.o: %.c ${HEADERS}
	${CC} ${CFLAGS} -c $< -o $@

%.bin: %.asm
	nasm $< -f bin -o $@

clean:
	rm -rf *.bin *.dis *.o os-image.bin *.elf
	rm -rf kernel/*.o boot/*.bin drivers/*.o boot/*.o