2014-10-15 09:19:16 +00:00
|
|
|
*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
|
2015-01-14 18:15:08 +00:00
|
|
|
for a few more lessons. Anyway, you will need a cross-compiler once we jump to developing in a higher
|
2014-10-15 09:19:16 +00:00
|
|
|
language, that is, C. [Read why](http://wiki.osdev.org/Why_do_I_need_a_Cross_Compiler%3F)
|
|
|
|
|
|
|
|
I'll be adapting the instructions [at the OSDev wiki](http://wiki.osdev.org/GCC_Cross-Compiler).
|
|
|
|
|
|
|
|
|
|
|
|
Required packages
|
|
|
|
-----------------
|
|
|
|
|
|
|
|
First, install the required packages. On linux, use your package distribution. On a Mac, [install brew](http://brew.sh/) 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
|
|
|
|
--------
|
|
|
|
|
2017-02-17 08:28:45 +00:00
|
|
|
Remember: always be careful before pasting walls of text from the internet. I recommend copying line by line.
|
2014-10-15 09:19:16 +00:00
|
|
|
|
|
|
|
```sh
|
|
|
|
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
|
|
|
|
---
|
|
|
|
```sh
|
|
|
|
cd /tmp/src
|
2017-10-06 05:24:47 +00:00
|
|
|
curl -O https://ftp.gnu.org/gnu/gcc/gcc-4.9.1/gcc-4.9.1.tar.bz2
|
2014-10-15 09:19:16 +00:00
|
|
|
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.
|
2020-09-18 07:22:27 +00:00
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
```
|