Minimalist educational operating system
Switch branches/tags
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
include
lib
src
.gitignore
COPYING
Makefile
README
qemu.sh

README

X1 - A minimalist educational operating system
==============================================

X1 is a very small operating system meant to introduce students to low-level
system programming. As a result, it focuses on clarity of explanation. It's
not meant to demonstrate state-of-the-art methods and algorithms, but rather
simple, naive ones that do the job, while providing pointers and references
to the more modern ways.

X1 is a single address space operating system, always running with the
highest privileges. There is no userspace, and no system calls. Despite
that, the operating system is also called the kernel.


Building
--------

X1 expects a Unix-like environment, including make and a GCC compilation
toolchain. It's been tested on a few Linux distributions such as Debian
and Arch.

Building the kernel is done using the make command from the source root
directory. The end result is a statically linked ELF [1] file named x1.
On Debian, the following packages are required :

 - build-essential
     Meta-package pulling the gcc and make packages, among others.
 - gcc-multilib
     Multilib support for GCC, which provides the 32-bits static libgcc
     library required to link the kernel on 64-bits machines.


Examining the kernel binary
---------------------------

The kernel can be examined with standard GNU binutils tools [2]. Here are
some common command line examples to obtain information directly from the
kernel binary :

 - objdump -d x1 | less
     Disassemble the kernel machine code.
 - readelf -aW x1 | less
     Display ELF information, such as headers and sections.
 - addr2line -e x1 0x1003f0
     Convert an address into a source location.
 - nm x1
     List symbol names.


Running
-------

X1 targets the x86 32-bits architecture only (i386) [3], and ignores some
advanced features such as virtual memory and SMP. It is compliant with the
original multiboot specification [4] and GRUB is the recommended boot loader.
It only supports legacy BIOS systems (no EFI/UEFI).

A simple way to run the kernel is to use the qemu.sh shell script, which
relies on the QEMU -kernel option to act as a multiboot boot loader.
On Debian, the following packages are required :

 - qemu
     The well known machine emulator.

When QEMU is running, you may enter (and leave) its monitor prompt using
the Ctrl-a c key sequence. The most useful monitor commands are :

 - info registers
     Print the content of all core registers.
 - info pic
     Print the state of the legacy PIC interrupt controller.

If you're interested in the details, the following commands may be of interest :

 - info mtree
     Print the various emulated address spaces.
 - info qtree
     Print the emulated device tree.


Getting started
---------------

Even a simple project like X1 requires broad knowledge, spanning from a basic
understanding of processors, memory, assembly and compilation toolchains. The
OSDev website [5] provides a good starting point to find information of decent
quality. Beyond that, readers are encouraged to refer to actual reference
documentation, and of course, search engines.

Here is a non-exhaustive list of topics readers should hopefully develop their
understanding of with this project, and are encouraged to briefly learn about
even before starting playing with X1 :

 - Processor architecture, including core registers, machine instructions
   and accessing memory through loads and stores.
 - Control of the link step through a linker script.
 - The concept of an executable format, including partitioning the content into
   sections, such as code and data sections. See ELF [1].
 - The C programming language, including common extensions, such as controlling
   alignment. The source code conforms to C99 [6] with some GNU extensions.

The two files reader should use as their entry points are :

 - src/boot_asm.S
     The assembly source file containing the very first instructions.
 - src/kernel.lds
     The linker script used to control the link step.

Sources organization
--------------------

The project sources are split into three directories :

- include
    This directory may only contain standard headers, normally provided
    by the "implementation" (e.g. the compiler and the C library) in a
    hosted environment. Because this is a kernel, the environment is
    free standing instead, so any additional standard service must be
    added manually. See ISO/IEC 9899:1999 5.1.2.1 "Freestanding environment"
    in the C99 specification for all the details.
- lib
    This directory contains external code used as a library by the kernel.
    These files are copied from the librbraun library [7] and are meant to
    provide a tiny and easily embedded "development kit".
- src
    This directory contains the actual kernel code.

The coding style used is borrowed from X1's big brother X15 [8].


References
----------

[1] ELF: http://refspecs.linuxbase.org/elf/elf.pdf
[2] GNU binutils : http://sourceware.org/binutils/docs-2.29/
[3] Intel combined manuals : https://software.intel.com/en-us/articles/intel-sdm
[4] Multiboot specification : https://www.gnu.org/software/grub/manual/multiboot/multiboot.html
[5] OSDev website : http://wiki.osdev.org/
[6] C99 specification : http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
[7] https://www.sceen.net/librbraun/
[8] https://www.sceen.net/~rbraun/x15/doc/style.9.html