Skip to content

quackitsquinn/novos

Repository files navigation

novos: A little kernel written in rust. (so I can learn osdev)

Running the kernel

To run the kernel, you need to have the following dependencies installed:

  • qemu
  • xorriso
  • rustc and cargo
    • You need to have the x86_64-unknown-none target installed, and nightly rust.
      rustup override set nightly
      rustup target add x86_64-unknown-none
      # This isn't strictly necessary, but it's a good idea to update installed toolchains
      rustup update

Then, you can run the kernel with the following command from the root of the repository:

cargo run

This will build the kernel, generate an image, and run it in QEMU.

Project structure

The project is split into several crates:

  • kbuild: A library for building the kernel. Used in build.rs and the test runner.
  • kernel: The main kernel crate.
  • kproc: Various procedural macros used in the kernel. Currently only contains the test macro.
  • kerial: A qemu serial driver for the kernel. Used for debugging.
  • kvmm: The kernel's virtual memory manager.`
  • kelp: A library for parsing elf files. Used for loading the kernel.
  • trampoline: The binary that loads the kernel into memory and jumps to it. Acts as a separator between the kernel and the bootloader.
  • cake: (that's a piece of cake) Utility crate for kernel space. Provides utilites and pulls in general purpose utilities like log and once

Some other folders that appear in the root of the repository:

  • boot_cfg: Configuration files for limine.
  • boot_images: ISO images generated by the build process.
  • output: Files generated by kserial commands.
  • tools: Various python scripts used for debugging. Both scripts are currently old and unused.

Debugging the kernel

All debugging is done through environment variables. The following environment variables are supported:

Runtime options

  • DEBUG: If set, QEMU will wait for a debugger to attach on port 1234.
  • QEMU_FLAGS: Additional flags to pass to QEMU.
  • VERBOSE: Shows QEMU's invocation command.
  • NO_DISPLAY: Disables the graphical display in QEMU.
  • KERNEL_MEM: Sets the amount of memory to allocate for the kernel in QEMU.
  • ISO: Override the iso file to boot from.
  • NO_EXIT: Prevents QEMU from exiting after the kernel exits.
  • REBUILD: Forces a rebuild of the test binary. This will have no effect on the kernel itself, as the kernel is not build at runtime.

Build-time options

  • ALLOC_DEBUG: If set, will print out information about memory allocations and deallocations.
  • REINSTALL_LIMINE: If set, limine will be re-downloaded from it's git repository and reinstalled.
  • ARTIFACT_DIR: The directory to store build artifacts in.
  • LIMINE_CONFIG: The path to the limine configuration file.
  • ISO_NAME: The name of the ISO file to generate.
  • ISO_ROOT: The directory to store ISO files in.

Alright, you hit the point where you don't have to read the rest of this README. Have fun tinkering with the kernel!

How I have developed this project

I have written this kernel in a kinda circular way. I have a general idea of what I want to implement, but I don't know how to implement it. So, I do the following:

  1. Do a whole heck of a lot of research about the feature I want to implement.
  2. Write some kinda poorly written code that does the thing I want to do.
  3. Work on other parts of the kernel for a while.
  4. Come back to the code with more knowledge and rewrite it.

I did this heavily for the memory management system, and am currently doing it for context switching and scheduling.

History

This project originally started as snakian. I was just trying to make a snake operating system, much inspired by jdh's Tetris OS Video. If you look at snakian, I want to warn you that the code is.. not the best.

I quickly in that project realized I wanted to do more than just a snake game (that I never even implemented anyways), so that project shifted to more of a general kernel. By that point though, I had made a lot of mistakes in the codebase, so I decided to start over. That's when I started this project.

This project does a lot differently than snakian. Snakian was almost a word-for-word following of Philipp Oppermann's blog. With nova though, I was confident enough to start off with something quite different. I used limine instead of bootloader, and implemented stuff with a lot more care and abstraction.

Personal note

This is the longest I have ever worked on a single project (15 months... holy cow), so I am really proud of this project. Yes, all this knowledge is incredibly niche, but I have learned a lot about the inner workings of computers and operating systems.

Also, Honestly, It's really cool to have gotten to this point when I remember at the start seeing so many resources saying to not even attempt it if you don't have 10 years of experience or like a bachelor's degree in computer science. I am a senior in high school with no formal education in computer science, and I have gotten to this point. I am really proud of myself for that.

If your reading this, and you are thinking about starting a project this massive and research-heavy, I say do it.

It wouldn't hurt to try, and you'd at least learn a lot.

Amazing resources

  • Philipp Oppermann's Blog
  • OSDev Wiki
    • Heavy on this. So much good information.
  • Redox Kernel
    • The whole redox project is helpful, but I have found the kernel to be the most helpful.
  • EuraliOS
    • Small kernel written in rust. Helped me with context switching. (Mainly the assembly stub)

About

An x86_64 kernel written in rust

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published