Commit 87f49887 authored by Thomas Hatzopoulos's avatar Thomas Hatzopoulos

updating to 2020 version of crates

parent 2614d38f
# in .cargo/config
[unstable]
build-std = ["core", "compiler_builtins"]
[build]
target = "x86_64-tantive_os.json"
[target.'cfg(target_os = "none")']
runner = "bootimage runner"
\ No newline at end of file
default:
image: "rust:latest"
stages:
- before_script
- doc
- build
- test
- deploy
variables:
CARGO_HOME: $CI_PROJECT_DIR/cargo
test:
image: rustlang/rust:nightly
stage: test
script:
- cargo version
build:
image: rustlang/rust:nightly
script:
- cargo build
cache:
paths:
- cargo/
- target/
before_script:
- cargo update
- rustup component add rust-src
- rustup component add llvm-tools-preview
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "array-init"
version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "bit_field"
version = "0.9.0"
......@@ -20,24 +12,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bootloader"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"fixedvec 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"llvm-tools 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"usize_conversions 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"x86_64 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)",
"xmas-elf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cast"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "fixedvec"
version = "0.2.4"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
......@@ -49,18 +24,8 @@ dependencies = [
]
[[package]]
name = "llvm-tools"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "nodrop"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "spin"
version = "0.4.10"
name = "rlibc"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
......@@ -72,33 +37,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "tantive_os"
version = "0.1.0"
dependencies = [
"bootloader 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"bootloader 0.9.8 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
"uart_16550 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rlibc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"uart_16550 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"volatile 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"x86_64 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)",
"x86_64 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "uart_16550"
version = "0.2.1"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"x86_64 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)",
"x86_64 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "usize_conversions"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ux"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "volatile"
version = "0.2.6"
......@@ -106,45 +62,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "x86_64"
version = "0.7.5"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"array-init 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"ux 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "xmas-elf"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"zero 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "zero"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum array-init 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "23589ecb866b460d3a0f1278834750268c607e8e28a1b982c907219f3178cd72"
"checksum bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed8765909f9009617974ab6b7d332625b320b33c326b1e9321382ef1999b5d56"
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
"checksum bootloader 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b15e5b7b9d9a8e427cf4270894f51ce288632a3a1a2cc6f8fda669d5446f98bd"
"checksum cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427"
"checksum fixedvec 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b395ef2adf62bdeefcd1b59ad0dd2225c6c333ec79656ea79ac5285c46d051ea"
"checksum bootloader 0.9.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0ad686b9b47363de7d36c05fb6885f17d08d0f2d15b1bc782a101fe3c94a2c7c"
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
"checksum llvm-tools 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "955be5d0ca0465caf127165acb47964f911e2bc26073e865deb8be7189302faf"
"checksum nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
"checksum spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ceac490aa12c567115b40b7b7fceca03a6c9d53d5defea066123debc83c5dc1f"
"checksum rlibc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc874b127765f014d792f16763a81245ab80500e2ad921ed4ee9e82481ee08fe"
"checksum spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
"checksum uart_16550 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "803ea8cb602dbb32c1a657a866d2dd79fe7dbeab0fb2ac667cb4dcc7de12a58b"
"checksum usize_conversions 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f70329e2cbe45d6c97a5112daad40c34cd9a4e18edb5a2a18fefeb584d8d25e5"
"checksum ux 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "88dfeb711b61ce620c0cb6fd9f8e3e678622f0c971da2a63c4b3e25e88ed012f"
"checksum uart_16550 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "e58fc40dc1712664fc9b0a7bd8ca2f21ab49960924fb245a80a05e1e92f3dfe9"
"checksum volatile 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6af0edf5b4faacc31fc51159244d78d65ec580f021afcef7bd53c04aeabc7f29"
"checksum x86_64 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)" = "997837f3913aac8f67164683258756d712376849906c8d609f844084bc03ef84"
"checksum xmas-elf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "22678df5df766e8d1e5d609da69f0c3132d794edf6ab5e75e7abcd2270d4cf58"
"checksum zero 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5f1bc8a6b2005884962297587045002d8cfb8dcec9db332f4ca216ddc5de82c5"
"checksum x86_64 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9144cdef072afe8afcbc511be8f421de5b3eb9f4b8ff7abff369bee38f91e7e3"
......@@ -3,21 +3,30 @@ name = "tantive_os"
version = "0.1.0"
authors = ["Thomas Hatzopoulos <[email protected]>"]
edition = "2018"
[[test]]
name = "should_panic"
harness = false
[dependencies]
bootloader = "0.6.4"
volatile = "0.2.3"
spin = "0.4.9"
x86_64 = "0.7.0"
bootloader = "0.9.8"
rlibc = "1.0.0"
volatile = "0.2.6"
spin = "0.5.2"
x86_64 = "0.11.0"
uart_16550 = "0.2.0"
[dependencies.lazy_static]
version = "1.0"
version = "1.4.0"
features = ["spin_no_std"]
[package.metadata.bootimage] # This target is used if no `--target` is passed
default-target = "x86_64-tantive_os.json"
[package.metadata.bootimage]
# The cargo subcommand that will be used for building the kernel.
#
# For building using the `cargo-xbuild` crate, set this to `xbuild`.
build-command = ["build"]
# The command invoked with the created bootimage (the "{}" will be replaced
# with the path to the bootable disk image)
......@@ -30,20 +39,10 @@ run-args = []
# Additional arguments passed to the run command for test executables
# Applies to `bootimage runner`
test-args = [
"-device", "isa-debug-exit,iobase=0xf4,iosize=0x04", "-serial", "stdio",
"-display", "none"
]
test-success-exit-code = 33 # (0x10 << 1) | 1
test-args = []
#TODO: Doesn't like integer {}
# An exit code that should be considered as success for test executables
#test-success-exit-code = {integer}
test-success-exit-code = 1
# The timeout for running a test through `bootimage test` or `bootimage runner` (in seconds)
test-timeout = 300
#Harness to false means I do not need to use teh test_runner
[[test]]
name = "should_panic"
harness = false
\ No newline at end of file
test-timeout = 10
Tantive OS: A Rust Kernel
# Tantive OS: A Rust Kernel
![BootScreen](boot.png?raw=true "BootScreen")
https://os.phil-opp.com/vga-text-mode/
TantiveOS is currently a minimal 64 bit Rust Kernel that prints to the screen using VGA Text mode.
Setup:
Prerequisites:
To build TantiveOS, you need to have the nightly version of rust with a version past 07-25-2020, and the following:
```
rustup component add rust-src
rustup component add llvm-tools-preview
cargo install bootimage
```
`sh setup.py'
Run:
`sh boot_in_qemu.sh`
To build a disk image and launch it using qemu, run:
```cargo run --release```
Tests:
cargo xtest
To run tests, run:
```cargo test```
emacs --font Iosevka DejaVuSansMono
Tests are run using a custom test framework that allows me to execute test functions inside of the kernel. The results of the tests are grabbed from qemu using qemu and bootimage.
\ No newline at end of file
boot.png

10.5 KB

#!/bin/sh
if [ "$1" = "--release" ]; then
echo 'building release version'
bootimage run --target x86_64-tantive_os.json --release
elif [ "$1" = "" ]; then
echo 'building debug version'
bootimage run --target x86_64-tantive_os.json
else
echo 'unknown args'
fi
\ No newline at end of file
status = [
"Zola Build", "Check Spelling"
]
delete_merged_branches = true
#!/bin/sh
# dd if=target/x86_64-blog_os/debug/bootimage-blog_os.bin of=/dev/sdX && sync
\ No newline at end of file
FROM rustlang/rust:nightly
ENV IMAGE_NAME=tantiveos-docker
RUN apt-get update && \
apt-get install -q -y --no-install-recommends \
nasm \
binutils \
grub-common \
xorriso \
grub-pc-bin && \
apt-get autoremove -q -y && \
apt-get clean -q -y && \
rm -rf /var/lib/apt/lists/* && \
cargo install xargo && \
rustup component add rust-src
ENV GOSU_VERSION 1.10
RUN set -ex; \
\
fetchDeps=' \
ca-certificates \
wget \
'; \
apt-get update; \
apt-get install -y --no-install-recommends $fetchDeps; \
rm -rf /var/lib/apt/lists/*; \
\
dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')"; \
wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; \
chmod +x /usr/local/bin/gosu; \
# verify that the binary works
gosu nobody true;
COPY entrypoint.sh /usr/local/bin/
COPY .bash_aliases /etc/skel/
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
CMD ["/bin/bash"]
# Building Blog OS using Docker
Inspired by [redox].
You just need `git`, `make`, and `docker`.
It is beter to use a non-privileged user to run the `docker` command, which is usually achieved by adding the user to the `docker` group.
## Run the container to build Blog OS
You can build the docker image using `make docker_build` and run it using `make docker_run`.
## Run the container interactively
You can use the `make` target `docker_interactive` to get a shell in the container.
## Clear the toolchain caches (Cargo & Rustup)
To clean the docker volumes used by the toolchain, you just need to run `make docker_clean`.
[redox]: https://github.com/redox-os/redox
## License
The source code is dual-licensed under MIT or the Apache License (Version 2.0). This excludes the `blog` directory.
#!/bin/sh
USER_NAME=raymusAntilles
USER_UID=${LOCAL_UID:-9001}
USER_GID=${LOCAL_GID:-9001}
groupadd --non-unique --gid $USER_GID $USER_NAME
useradd --non-unique --create-home --uid $USER_UID --gid $USER_GID $USER_NAME
export HOME=/home/$USER_NAME
TESTFILE=$RUSTUP_HOME/settings.toml
CACHED_UID=$(stat -c "%u" $TESTFILE)
CACHED_GID=$(stat -c "%g" $TESTFILE)
if [ $CACHED_UID != $USER_UID ] || [ $USER_GID != $CACHED_GID ]; then
chown $USER_UID:$USER_GID -R $CARGO_HOME $RUSTUP_HOME
fi
exec gosu $USER_NAME "[email protected]"
nightly
\ No newline at end of file
nightly
#!/bin/sh
cargo install cargo-xbuild
rustup component add rust-src
rustup component add llvm-tools-preview
cargo install bootimage --version "^0.7.3"
......@@ -4,15 +4,32 @@
#![test_runner(crate::test_runner)]
#![reexport_test_harness_main = "test_main"]
extern crate rlibc;
use core::panic::PanicInfo;
pub mod serial;
pub mod vga_buffer;
pub fn test_runner(tests: &[&dyn Fn()]) {
pub trait Testable {
fn run(&self) -> ();
}
impl<T> Testable for T
where
T: Fn(),
{
fn run(&self) {
serial_print!("{}...\t", core::any::type_name::<T>());
self();
serial_println!("[ok]");
}
}
pub fn test_runner(tests: &[&dyn Testable]) {
serial_println!("Running {} tests", tests.len());
for test in tests {
test();
test.run();
}
exit_qemu(QemuExitCode::Success);
}
......@@ -52,4 +69,4 @@ pub extern "C" fn _start() -> ! {
#[panic_handler]
fn panic(info: &PanicInfo) -> ! {
test_panic_handler(info)
}
}
\ No newline at end of file
......@@ -6,6 +6,7 @@
#![reexport_test_harness_main = "test_main"]
use core::panic::PanicInfo;
mod serial;
extern crate rlibc;
mod vga_buffer;
......@@ -33,3 +34,8 @@ fn panic(info: &PanicInfo) -> ! {
fn panic(info: &PanicInfo) -> ! {
tantive_os::test_panic_handler(info)
}
#[test_case]
fn trivial_assertion() {
assert_eq!(1, 1);
}
\ No newline at end of file
......@@ -34,4 +34,4 @@ macro_rules! serial_println {
($fmt:expr) => ($crate::serial_print!(concat!($fmt, "\n")));
($fmt:expr, $($arg:tt)*) => ($crate::serial_print!(
concat!($fmt, "\n"), $($arg)*));
}
}
\ No newline at end of file
use core::fmt;
use lazy_static::lazy_static;
use spin::Mutex;
use volatile::Volatile; // adds safe interior mutability to static WRITER
use volatile::Volatile; // adds safe interior mutability to static Writer
// Provides a global writer that can be used as an interface from other modules w/o carrying a Writer instance around
lazy_static! {
/// A global `Writer` instance that can be used for printing to the VGA text buffer.
///
......@@ -14,6 +14,7 @@ lazy_static! {
});
}
/// The standard color palette in VGA text mode.
#[allow(dead_code)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
......@@ -38,15 +39,17 @@ pub enum Color {
/// A combination of a foreground and a background color.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(transparent)] // makes sure colorcode has the eaxt same data layour as an u8
#[repr(transparent)] // makes sure colorcode has the exact same data layer as an u8
struct ColorCode(u8);
impl ColorCode {
/// Create a new `ColorCode` with the given foreground and background colors.
fn new(foreground: Color, background: Color) -> ColorCode {
ColorCode((background as u8) << 4 | (foreground as u8))
}
}
/// A screen character in the VGA text buffer, consisting of an ASCII character and a `ColorCode`.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(C)] // Ordering in default structs is undefined in Rust so repr(c) fixes that
struct ScreenChar {
......@@ -54,14 +57,21 @@ struct ScreenChar {
color_code: ColorCode,
}
/// The height of the text buffer (normally 25 lines).
const BUFFER_HEIGHT: usize = 25;
/// The width of the text buffer (normally 80 columns).
const BUFFER_WIDTH: usize = 80;
/// A structure representing the VGA text buffer.
#[repr(transparent)]
struct Buffer {
chars: [[Volatile<ScreenChar>; BUFFER_WIDTH]; BUFFER_HEIGHT],
}
/// A writer type that allows writing ASCII bytes and strings to an underlying `Buffer`.
///
/// Wraps lines at `BUFFER_WIDTH`. Supports newline characters and implements the
/// `core::fmt::Write` trait.
pub struct Writer {
column_position: usize,
color_code: ColorCode,
......@@ -69,6 +79,9 @@ pub struct Writer {
}
impl Writer {
/// Writes an ASCII byte to the buffer.
///
/// Wraps lines at `BUFFER_WIDTH`. Supports the `\n` newline character.
pub fn write_byte(&mut self, byte: u8) {
match byte {
b'\n' => self.new_line(),
......@@ -90,7 +103,12 @@ impl Writer {
}
}
pub fn write_string(&mut self, s: &str) {
/// Writes the given ASCII string to the buffer.
///
/// Wraps lines at `BUFFER_WIDTH`. Supports the `\n` newline character. Does **not**
/// support strings with non-ASCII characters, since they can't be printed in the VGA text
/// mode.
fn write_string(&mut self, s: &str) {
for byte in s.bytes() {
match byte {
// printable ASCII byte or newline
......@@ -100,21 +118,8 @@ impl Writer {
}
}
}
}
//
// }
use core::fmt;
impl fmt::Write for Writer {
fn write_str(&mut self, s: &str) -> fmt::Result {
self.write_string(s);
Ok(())
}
}
impl Writer {
/// Shifts all lines one line up and clears the last row.
fn new_line(&mut self) {
for row in 1..BUFFER_HEIGHT {
for col in 0..BUFFER_WIDTH {
......@@ -126,6 +131,7 @@ impl Writer {
self.column_position = 0;
}
/// Clears a row by overwriting it with blank characters.
fn clear_row(&mut self, row: usize) {
let blank = ScreenChar {
ascii_character: b' ',
......@@ -137,52 +143,51 @@ impl Writer {
}
}
impl fmt::Write for Writer {
fn write_str(&mut self, s: &str) -> fmt::Result {
self.write_string(s);
Ok(())
}
}
/// Like the `print!` macro in the standard library, but prints to the VGA text buffer.
#[macro_export]
macro_rules! print {
($($arg:tt)*) => ($crate::vga_buffer::_print(format_args!($($arg)*)));
}
/// Like the `println!` macro in the standard library, but prints to the VGA text buffer.
#[macro_export]
macro_rules! println {
() => ($crate::print!("\n"));
($($arg:tt)*) => ($crate::print!("{}\n", format_args!($($arg)*)));
}
/// Prints the given formatted string to the VGA text buffer through the global `WRITER` instance.
#[doc(hidden)]
pub fn _print(args: fmt::Arguments) {
use core::fmt::Write;
WRITER.lock().write_fmt(args).unwrap();
}
#[cfg(test)]
use crate::{serial_print, serial_println};
// #[test_case]
// fn test_println_simple() {
// serial_print!("test_println... ");
// println!("test_println_simple output");
// serial_println!("[ok]");
// }
// // in src/vga_buffer.rs
// #[test_case]
// fn test_println_many() {
// serial_print!("test_println_many... ");
// for _ in 0..200 {
// println!("test_println_many output");
// }
// serial_println!("[ok]");