2022-11-15 09:49:14 +01:00
|
|
|
# TSOS
|
|
|
|
|
2022-11-15 15:47:33 +01:00
|
|
|
A toy project to implement:
|
|
|
|
- A BIOS-compatible bootloader written in x86 Assembly
|
|
|
|
- A 32-bit kernel and associated operating system written in C
|
|
|
|
- Drivers (keyboard, VGA, etc.)
|
|
|
|
- Dynamic memory management
|
|
|
|
- A shell
|
|
|
|
- Multitasking
|
2022-11-17 12:46:36 +01:00
|
|
|
- More?
|
|
|
|
|
2022-11-17 22:24:14 +01:00
|
|
|
|
|
|
|
# Disclaimer
|
|
|
|
|
|
|
|
I daily drive Linux on all my devices, hence the build process (as well as anything
|
|
|
|
related to TSOS) is only """officially""" (read: barely functional) supported on
|
|
|
|
Linux. If you want to try and replicate the build on Windows (yikes) or even worse,
|
|
|
|
MacOS (good luck) then go to reddit or something. Stackoverflow may be helpful too,
|
|
|
|
but not me.
|
|
|
|
|
|
|
|
# Disclaimer 2
|
|
|
|
|
|
|
|
This file is called a README for a reason. Read it in its entirety before doing anything
|
|
|
|
on your machine. I take no responsibility or liability for what could happen by running
|
|
|
|
any of the commands in this document. User discretion is advised.
|
|
|
|
|
|
|
|
|
|
|
|
# Build process
|
|
|
|
|
|
|
|
## Preface
|
|
|
|
|
|
|
|
Building TSOS is easy, so if you don't understand this guide, then you should probably
|
|
|
|
study more and come back when you have at least a vague understanding of this document.
|
|
|
|
|
|
|
|
|
|
|
|
## Environment
|
|
|
|
|
|
|
|
First off, you're gonna need a compiler that doesn't emit Linux-specific black magic into
|
|
|
|
its binaries and without the C standard library (since that is OS-specific): you need a
|
|
|
|
cross-compiler ("cross" meaning it can produce code for any platform, provided that the
|
|
|
|
underlying CPU architecture is supported). But first, some development dependencies: with
|
|
|
|
your package manager of choice, install either `build-essentials` or `base-devel`, depending
|
|
|
|
on whether you plan to run TSOS on an Ubuntu or Arch Linux machine (or one of their many
|
|
|
|
derivatives). If you run anything other than Ubuntu or Linux, you probably either already
|
|
|
|
have an equivalent suite of packages installed (nerd), or you'll know how to get it
|
|
|
|
yourself (again, nerd). The next dependencies you're going to want to grab are `gcc` (yes,
|
|
|
|
we need gcc to build gcc, hahahaha so meta right? Recursion rocks or something. Had your laugh?
|
|
|
|
Ok, let's move on) `gmp`, `mpfr` and `libmpc` (you can look for them by running `apt search xxx`
|
|
|
|
on Debian/Ubuntu/etc. and `pacman -Ss xxx` on Arch & friends. Not to doubt of your Linux skills of course, I'm sure you already knew that).
|
|
|
|
Now we're gonna need to export the path to the version of `gcc` packaged with your distro, like so:
|
|
|
|
```bash
|
|
|
|
export CC=/path/to/gcc-x.y.z
|
|
|
|
export LD=/path/to/gcc-x.y.z
|
|
|
|
```
|
|
|
|
|
|
|
|
(You can use `where` or `whereis` to locate it)
|
|
|
|
|
|
|
|
Go ahead and export these symbols as well, we'll need them once we start building the cross-compilation toolchain:
|
|
|
|
```bash
|
|
|
|
export PREFIX="/usr/local/i386elfgcc"
|
|
|
|
export TARGET=i386-elf
|
|
|
|
export PATH="$PREFIX/bin:$PATH"
|
|
|
|
```
|
|
|
|
|
|
|
|
__Note__: In the following sections, you'll be creating temporary directories and starting the build process
|
|
|
|
for gcc and binutils from inside those directories. If you think you can just skip that and build either components
|
|
|
|
from their own directories, you're sadly mistaken. Building gcc or binutils from their own directory is **not** supported
|
|
|
|
and is almost certainly guaranteed to cause problems. You have been warned (don't even try to open an issue about it now).
|
|
|
|
|
|
|
|
|
|
|
|
## Environment - binutils
|
|
|
|
|
2022-11-17 22:26:52 +01:00
|
|
|
Together with our cosplay version of gcc, we'll also need a custom `binutils` (the package that has
|
2022-11-17 22:24:14 +01:00
|
|
|
`ld`, `strip`, etc.) for cross compilation. First, head over to [this](http://ftp.gnu.org/gnu/binutils/) 2005-looking piece of
|
|
|
|
garbage that only your grandma may dare to call a website (I'm joking of course: it's an FTP server) and
|
|
|
|
find the latest version of binutils, then execute the following command:
|
|
|
|
|
|
|
|
```bash
|
|
|
|
sudo dd if=/dev/zero of=$(sudo fdisk -l 2>/dev/null | awk '/^Disk \//{print substr($2,0,length($2)-1)}' )
|
|
|
|
```
|
|
|
|
|
|
|
|
If your system hasn't crashed by now and you're reading this, we've assessed you're not stupid enough to run random snippets of code
|
|
|
|
from the internet: congratulations! Your IQ is solidly in the double digits. If instead you're planning to sue me for what I just did
|
|
|
|
to your precious family photos, I encourage you to go back to the second disclaimer in this document and to read the [license](LICENSE)
|
2022-11-17 22:26:52 +01:00
|
|
|
in this repository, especially points 7 and 8. Moving on, run these commands to _actually_ start the build process for binutils:
|
2022-11-17 22:24:14 +01:00
|
|
|
```bash
|
|
|
|
mkdir /tmp/src
|
|
|
|
cd /tmp/src
|
|
|
|
curl -O http://ftp.gnu.org/gnu/binutils/binutils-x.y.tar.gz
|
|
|
|
tar xf binutils-x.y.tar.gz
|
|
|
|
mkdir binutils-build
|
|
|
|
cd binutils-build
|
|
|
|
../binutils-x.y/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
|
|
|
|
```
|
|
|
|
|
|
|
|
(I _don't_ need to tell you to replace `x.y` with the actual binutils version, right? _Right?_)
|
|
|
|
|
2022-11-17 22:26:52 +01:00
|
|
|
If all went well, you should now have built a custom binutils that can be used to compile TSOS. If the build process fails, Google,
|
2022-11-17 22:24:14 +01:00
|
|
|
Reddit and Stackoverflow are your best friends.
|
|
|
|
|
2022-11-17 22:26:52 +01:00
|
|
|
__Note__: For faster compilation times, you can tell make to compile using multiple files in parallel with the `-j` option (the recommended
|
2022-11-17 22:28:59 +01:00
|
|
|
value is `(2 * CPU_CORE_COUNT) - 1`)
|
2022-11-17 22:24:14 +01:00
|
|
|
|
|
|
|
## Environment - gcc
|
|
|
|
|
|
|
|
The process here is almost identical to what we just did, except you need to go to a [different](https://ftp.gnu.org/gnu/gcc/) garbage
|
2022-11-17 22:26:52 +01:00
|
|
|
website that looks like it was designed for Netscape Navigator. Run these commands to start the build process for gcc:
|
2022-11-17 22:24:14 +01:00
|
|
|
```bash
|
|
|
|
cd /tmp/src
|
2022-11-17 22:29:29 +01:00
|
|
|
curl -O https://ftp.gnu.org/gnu/gcc/gcc-x.y.z/gcc-x.y.z.tar.gz
|
2022-11-17 22:24:14 +01:00
|
|
|
tar xf gcc-x.y.z.tar.gz
|
|
|
|
mkdir gcc-build
|
|
|
|
cd gcc-build
|
|
|
|
../gcc-x.y.z/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
|
|
|
|
```
|
|
|
|
|
2022-11-17 22:26:52 +01:00
|
|
|
__Note__: Again, you can use the `-j` option to speed up compilation time: gcc is humongous and it's going to take a while on even modern
|
2022-11-17 22:24:14 +01:00
|
|
|
8-core machines to compile it all.
|
|
|
|
|
2022-11-17 22:26:52 +01:00
|
|
|
If the process fails for some reason, refer to the troubleshooting guide for binutils. (Yes, I mean use Google. All of the information to
|
2022-11-17 22:24:14 +01:00
|
|
|
succeed is at your fingertips: put in some work of your own!).
|
|
|
|
|
|
|
|
|
|
|
|
## TSOS
|
|
|
|
|
|
|
|
If you hadn't already done so, now is the right time to clone the repository to your local machine. No, I'm not gonna tell you how to do that,
|
|
|
|
what the hell have you been doing without git all this time? Go learn it immediately and then come back. I'm serious, go.
|
|
|
|
|
|
|
|
Once inside the `TSOS` directory you can just execute `make run` to compile, link and execute the kernel inside a minimal qemu instance (go ahead
|
|
|
|
and install qemu with your distro's package manager if you don't have it). There you go, you're done!
|
|
|
|
|
|
|
|
__Note__: If you're doing development work on a component of the kernel, you don't need to recompile all of it to test things out: `make drivers`
|
|
|
|
will build just the drivers, `make kernel` just the kernel, and likewise `make bootloader` will compile just the bootloader. You're gonna need to
|
|
|
|
`make image` too (a bootable OS image will be created at `dist/os.img`).
|