diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c987d3e..d9a40b8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,30 +5,44 @@ jobs: build: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v3 - - name: Install Rust + - name: Install APT packages + uses: awalsh128/cache-apt-pkgs-action@v1 + with: + packages: build-essentials nasm wget + + - name: Install Rust for x86-64 Linux uses: actions-rs/toolchain@v1 with: toolchain: nightly override: true target: x86_64-unknown-linux-gnu - components: rust-src + - name: Install Rust for x86_64 UEFI + uses: actions-rs/toolchain@v1 + with: + toolchain: nightly + target: x86_64-unknown-uefi + - name: Install Rust for i686 UEFI + uses: actions-rs/toolchain@v1 + with: + toolchain: nightly + target: i686-unknown-uefi + - name: Install Rust for x86_64 UEFI + uses: actions-rs/toolchain@v1 + with: + toolchain: nightly + target: x86_64-unknown-uefi - name: Install cargo-make run: cargo install --no-default-features cargo-make - - uses: awalsh128/cache-apt-pkgs-action@v1 - with: - packages: make nasm dosfstools mtools zstd unzip wget + - name: Install towbootctl + run: cargo install --git https://github.com/hhuOS/towboot --features=binary -Z bindeps towbootctl - name: Build - run: cargo make --no-workspace - - - name: Create artifact - run: tar -czvf d3os.tar.gz d3os.img run.sh README.md + run: cargo make --no-workspace image - name: Upload artifact uses: actions/upload-artifact@v3 with: name: D3OS - path: d3os.tar.gz \ No newline at end of file + path: d3os.img \ No newline at end of file diff --git a/.gitignore b/.gitignore index 7098278..7eb3425 100644 --- a/.gitignore +++ b/.gitignore @@ -126,11 +126,7 @@ Cargo.lock # End of https://www.toptal.com/developers/gitignore/api/rust,clion+iml,VisualStudioCode d3os.img -d3os.iso -efi/OVMF.fd +RELEASEX64_OVMF.fd loader/kernel.elf loader/initrd.tar -loader/initrd -loader/towboot/towboot-x64.efi -loader/grub/iso/boot/kernel.elf -loader/grub/iso/boot/initrd.tar \ No newline at end of file +loader/initrd \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index e753aa3..df514a9 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -32,8 +32,8 @@ "label": "qemu-gdb", "type": "shell", "isBackground": true, - "command": "${workspaceRoot}/run.sh", - "args": ["--debug", "vscode"], + "command": "cargo", + "args": [ "make", "--no-workspace", "--profile", "development", "debug" ], "problemMatcher": [ { "pattern": [ @@ -47,7 +47,7 @@ "background": { "activeOnStart": true, "beginsPattern": ".", - "endsPattern": "Debugging with VSCode...", + "endsPattern": "Ready to debug", } } ], diff --git a/Makefile.toml b/Makefile.toml index 530f7c1..6c9bda0 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -1,13 +1,44 @@ [env] BOOTLOADER_DIRECTORY = "${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/loader" INITRD_DIRECTORY = "${BOOTLOADER_DIRECTORY}/initrd" +OVMF_URL = "https://retrage.github.io/edk2-nightly/bin/RELEASEX64_OVMF.fd" +LINKER = "ld" +LINKER_MAC = "x86_64-elf-ld" +PATH = "${PATH}:~/.cargo/bin" [tasks.default] -alias = "towboot" +alias = "qemu" + +# Run tasks + +[tasks.debug] +command = "qemu-system-x86_64" +args = [ "-S", "-gdb", "tcp::1234", "-machine", "q35,pcspk-audiodev=audio0", "-m", "128M", "-cpu", "qemu64", "-bios", "RELEASEX64_OVMF.fd", "-boot", "d", "-vga", "std", "-rtc", "base=localtime", "-drive", "driver=raw,node-name=boot,file.driver=file,file.filename=d3os.img", "-audiodev", "id=audio0,driver=pa" ] +dependencies = [ "debug-signal-vscode" ] + +[tasks.debug.mac] +args = [ "-S", "-gdb", "tcp::1234", "-machine", "q35,pcspk-audiodev=audio0", "-m", "128M", "-cpu", "qemu64", "-bios", "RELEASEX64_OVMF.fd", "-boot", "d", "-vga", "std", "-rtc", "base=localtime", "-drive", "driver=raw,node-name=boot,file.driver=file,file.filename=d3os.img", "-audiodev", "id=audio0,driver=coreaudio" ] + +[tasks.debug-signal-vscode] +command = "echo" +args = [ "Ready to debug" ] +dependencies = [ "image", "ovmf" ] + +[tasks.qemu] +command = "qemu-system-x86_64" +args = [ "-machine", "q35,pcspk-audiodev=audio0", "-m", "128M", "-cpu", "qemu64", "-bios", "RELEASEX64_OVMF.fd", "-boot", "d", "-vga", "std", "-rtc", "base=localtime", "-drive", "driver=raw,node-name=boot,file.driver=file,file.filename=d3os.img", "-audiodev", "id=audio0,driver=pa" ] +dependencies = [ "image", "ovmf" ] + +[tasks.qemu.mac] +args = [ "-machine", "q35,pcspk-audiodev=audio0", "-m", "128M", "-cpu", "qemu64", "-bios", "RELEASEX64_OVMF.fd", "-boot", "d", "-vga", "std", "-rtc", "base=localtime", "-drive", "driver=raw,node-name=boot,file.driver=file,file.filename=d3os.img", "-audiodev", "id=audio0,driver=coreaudio" ] + +[tasks.ovmf] +command = "wget" +args = [ "-N", "${OVMF_URL}" ] # Build tasks -[tasks.link_members] +[tasks.link-members] run_task = { name = "link", fork = true } dependencies = [ "create-initrd-directory" ] @@ -15,42 +46,31 @@ dependencies = [ "create-initrd-directory" ] command = "mkdir" args = [ "-p", "${INITRD_DIRECTORY}" ] -[tasks.towboot] -cwd = "${BOOTLOADER_DIRECTORY}/towboot" -command = "./build.sh" -dependencies = [ "link_members", "initrd" ] - -[tasks.grub] -cwd = "${BOOTLOADER_DIRECTORY}/grub" -command = "grub-mkrescue" -args = [ "-o", "${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/d3os.iso", "iso/" ] -dependencies = [ "grub-copy-files" ] - -[tasks.grub-copy-files] -cwd = "${BOOTLOADER_DIRECTORY}" -command = "cp" -args = [ "kernel.elf", "initrd.tar", "grub/iso/boot" ] -dependencies = [ "link_members", "initrd" ] - [tasks.initrd] cwd = "${INITRD_DIRECTORY}" command = "tar" args = [ "-cf", "${BOOTLOADER_DIRECTORY}/initrd.tar", "hello", "shell", "uptime", "date" ] -dependencies = [ "link_members" ] +dependencies = [ "link-members" ] + +[tasks.image] +cwd = "${BOOTLOADER_DIRECTORY}" +command = "towbootctl" +args = [ "image", "--target", "${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/d3os.img", "--", "-config", "towboot.toml"] +dependencies = [ "link-members", "initrd" ] # Cleanup tasks [tasks.clean] -dependencies = [ "clean_workspace", "clean_members" ] +dependencies = [ "clean-workspace", "clean-members" ] -[tasks.clean_workspace] +[tasks.clean-workspace] command = "rm" args = [ "-rf", "${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/d3os.img", "${BOOTLOADER_DIRECTORY}/kernel.elf", "${BOOTLOADER_DIRECTORY}/initrd.tar", - "${BOOTLOADER_DIRECTORY}/grub/iso/boot/kernel.elf", - "${BOOTLOADER_DIRECTORY}/grub/iso/boot/initrd.tar" ] + "${INITRD_DIRECTORY}", + "RELEASEX64_OVMF.fd" ] -[tasks.clean_members] +[tasks.clean-members] run_task = { name = "clean", fork = true } diff --git a/README.md b/README.md index 9991248..468d714 100644 --- a/README.md +++ b/README.md @@ -1,42 +1,54 @@ # D3OS A new research operating system, developed by the [operating systems group](https://www.cs.hhu.de/en/research-groups/operating-systems.html) of the department of computer science at [Heinrich Heine University Düsseldorf](https://www.hhu.de) -## Requirements +

+ +

-For building D3OS, a _rust nightly_ toolchain is needed. To install _rust_ use [rustup](https://rustup.rs/). +

+ + + +

-`rustup toolchain install nightly` +## Requirements -And activate it for the current folder with: +For building D3OS, a _rust nightly_ toolchain is needed. To install _rust_ use [rustup](https://rustup.rs/). -`rustup override set nightly` +``` +rustup toolchain install nightly +rustup override set nightly +``` To run the build commands _cargo-make_ is required. Install it with: -`cargo install --no-default-features cargo-make` +``` +cargo install --no-default-features cargo-make +``` Further the following packages for Debian/Ubuntu based systems (or their equivalent packages on other distributions) need to be installed: -`apt install build-essential nasm mtools fdisk zstd` - -To run the final OS image _QEMU_ is required: - -`apt install qemu-system-x86_64` - -## Build - -For a full build run: +``` +apt install build-essential nasm wget qemu-system-x86_64 +``` -`cargo make --no-workspace` +D3OS depends on the rust-based bootloader [towboot](https://github.com/hhuOS/towboot), which provides the `towbootctl` utility for creating bootable images. Install it with: -This will produce _d3os.img_. +``` +rustup target install i686-unknown-uefi x86_64-unknown-uefi +cargo install --git https://github.com/hhuOS/towboot --features=binary -Z bindeps towbootctl +``` -## Run +## Build and Run -To run the image, build it first and then use: +To build D3OS and run it in QEMU, just execute: -`./run.sh` +``` +cargo make --no-workspace +``` -This will execute the operating system with _QEMU_. +To only build the bootable image _d3os.img_, run: -For more information see `run.sh --help`. +``` +cargo make --no-workspace image +``` diff --git a/loader/grub/iso/boot/grub/grub.cfg b/loader/grub/iso/boot/grub/grub.cfg deleted file mode 100644 index e4e466b..0000000 --- a/loader/grub/iso/boot/grub/grub.cfg +++ /dev/null @@ -1,20 +0,0 @@ -set timeout=0 -set default=0 -set menu_color_highlight=light-blue/light-green - -if [ x$feature_all_video_module = xy ]; then - insmod all_video -else - insmod efi_gop - insmod efi_uga - insmod ieee1275_fb - insmod vbe - insmod vga - insmod video_bochs - insmod video_cirrus -fi - -menuentry "D3OS" { - multiboot2 /boot/kernel.elf - module2 /boot/initrd.tar initrd -} \ No newline at end of file diff --git a/loader/towboot/towboot.toml b/loader/towboot.toml similarity index 52% rename from loader/towboot/towboot.toml rename to loader/towboot.toml index 73a9486..97901d7 100644 --- a/loader/towboot/towboot.toml +++ b/loader/towboot.toml @@ -5,5 +5,5 @@ log_level = "info" [entries] [entries.d3os] name = "D3OS" - image = "\\kernel.elf" - modules = [ { image = "\\initrd.tar", argv = "initrd" } ] \ No newline at end of file + image = "kernel.elf" + modules = [ { image = "initrd.tar", argv = "initrd" } ] \ No newline at end of file diff --git a/loader/towboot/build.sh b/loader/towboot/build.sh deleted file mode 100755 index b92a6fa..0000000 --- a/loader/towboot/build.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash - -readonly TOWBOOT_VERSION="0.8.1" -readonly FILE_LIST=("towboot-x64.efi" "towboot.toml" "../kernel.elf" "../initrd.tar") -readonly IMAGE="../../d3os.img" - -if [[ ! -f "towboot-x64.efi" ]]; then - wget -O towboot-x64.efi "https://github.com/hhuOS/towboot/releases/download/v${TOWBOOT_VERSION}/towboot-v${TOWBOOT_VERSION}-x86_64.efi" || exit 1 -fi - -SIZE=0; -for file in "${FILE_LIST[@]}"; do - SIZE=$(($SIZE + $(wc -c ${file} | cut -d ' ' -f 1))) -done - -readonly SECTORS=$(((${SIZE} / 512) + 2048)) - -mformat -i part.img -C -T ${SECTORS} || exit 1 -mmd -i part.img efi || exit 1 -mmd -i part.img efi/boot || exit 1 -mcopy -i part.img towboot-x64.efi ::efi/boot/bootx64.efi || exit 1 -mcopy -i part.img towboot.toml :: || exit 1 -mcopy -i part.img ../kernel.elf :: || exit 1 -mcopy -i part.img ../initrd.tar :: || exit 1 - -fallocate -l 1M fill.img || exit 1 -cat fill.img part.img fill.img > "${IMAGE}" || exit 1 -echo -e "g\\nn\\n1\\n2048\\n+${SECTORS}\\nt\\n1\\nw\\n" | fdisk "${IMAGE}" || exit 1 - -rm -f fill.img part.img || exit 1 diff --git a/media/hhu.svg b/media/hhu.svg new file mode 100644 index 0000000..3521884 --- /dev/null +++ b/media/hhu.svg @@ -0,0 +1,190 @@ + + + + + + + + + + + + + + diff --git a/os/application/date/Makefile.toml b/os/application/date/Makefile.toml index e1a6dfe..e6e5f69 100644 --- a/os/application/date/Makefile.toml +++ b/os/application/date/Makefile.toml @@ -26,10 +26,13 @@ command = "cargo" args = [ "build", "-Z", "build-std=core,alloc", "-Z", "build-std-features=compiler-builtins-mem", "--target", "${CARGO_CFG_TARGET_FAMILY}", "${CARGO_BUILD_OPTION}" ] [tasks.link] -command = "ld" +command = "${LINKER}" args = [ "-n", "-T", "${LINKER_FILE}", "-o", "${APPLICATION}", "${RUST_OBJECT}" ] dependencies = [ "compile" ] +[tasks.link.mac] +command = "${LINKER_MAC}" + # Cleanup tasks [tasks.clean] diff --git a/os/application/hello/Makefile.toml b/os/application/hello/Makefile.toml index e1a6dfe..e6e5f69 100644 --- a/os/application/hello/Makefile.toml +++ b/os/application/hello/Makefile.toml @@ -26,10 +26,13 @@ command = "cargo" args = [ "build", "-Z", "build-std=core,alloc", "-Z", "build-std-features=compiler-builtins-mem", "--target", "${CARGO_CFG_TARGET_FAMILY}", "${CARGO_BUILD_OPTION}" ] [tasks.link] -command = "ld" +command = "${LINKER}" args = [ "-n", "-T", "${LINKER_FILE}", "-o", "${APPLICATION}", "${RUST_OBJECT}" ] dependencies = [ "compile" ] +[tasks.link.mac] +command = "${LINKER_MAC}" + # Cleanup tasks [tasks.clean] diff --git a/os/application/shell/Makefile.toml b/os/application/shell/Makefile.toml index e1a6dfe..e6e5f69 100644 --- a/os/application/shell/Makefile.toml +++ b/os/application/shell/Makefile.toml @@ -26,10 +26,13 @@ command = "cargo" args = [ "build", "-Z", "build-std=core,alloc", "-Z", "build-std-features=compiler-builtins-mem", "--target", "${CARGO_CFG_TARGET_FAMILY}", "${CARGO_BUILD_OPTION}" ] [tasks.link] -command = "ld" +command = "${LINKER}" args = [ "-n", "-T", "${LINKER_FILE}", "-o", "${APPLICATION}", "${RUST_OBJECT}" ] dependencies = [ "compile" ] +[tasks.link.mac] +command = "${LINKER_MAC}" + # Cleanup tasks [tasks.clean] diff --git a/os/application/uptime/Makefile.toml b/os/application/uptime/Makefile.toml index e1a6dfe..e6e5f69 100644 --- a/os/application/uptime/Makefile.toml +++ b/os/application/uptime/Makefile.toml @@ -26,10 +26,13 @@ command = "cargo" args = [ "build", "-Z", "build-std=core,alloc", "-Z", "build-std-features=compiler-builtins-mem", "--target", "${CARGO_CFG_TARGET_FAMILY}", "${CARGO_BUILD_OPTION}" ] [tasks.link] -command = "ld" +command = "${LINKER}" args = [ "-n", "-T", "${LINKER_FILE}", "-o", "${APPLICATION}", "${RUST_OBJECT}" ] dependencies = [ "compile" ] +[tasks.link.mac] +command = "${LINKER_MAC}" + # Cleanup tasks [tasks.clean] diff --git a/os/kernel/Makefile.toml b/os/kernel/Makefile.toml index 2111c35..92a65bc 100644 --- a/os/kernel/Makefile.toml +++ b/os/kernel/Makefile.toml @@ -31,10 +31,13 @@ command = "nasm" args = [ "-f", "elf64", "-w+error=label-redef-late", "-o", "${ASM_OBJECT}", "${SOURCE_DIRECOTRY}/boot.asm" ] [tasks.link] -command = "ld" +command = "${LINKER}" args = [ "-n", "-T", "${LINKER_FILE}", "-o", "${KERNEL}", "${ASM_OBJECT}", "${RUST_OBJECT}" ] dependencies = [ "compile", "build-asm" ] +[tasks.link.mac] +command = "${LINKER_MAC}" + # Cleanup tasks [tasks.clean] diff --git a/run.sh b/run.sh deleted file mode 100755 index 649086d..0000000 --- a/run.sh +++ /dev/null @@ -1,197 +0,0 @@ -#!/bin/bash - -readonly CONST_OVMF_URL="https://retrage.github.io/edk2-nightly/bin/RELEASEX64_OVMF.fd" - -readonly CONST_QEMU_BIN="qemu-system-x86_64" -readonly CONST_QEMU_MACHINE_PC="pc" -readonly CONST_QEMU_CPU="qemu64" -readonly CONST_QEMU_MACHINE_PC_KVM="pc,accel=kvm,kernel-irqchip=split" -readonly CONST_QEMU_DEFAULT_RAM="128M" -readonly CONST_QEMU_BIOS_EFI="efi/OVMF.fd" -readonly CONST_QEMU_ARGS="-boot d -vga std -rtc base=localtime -device isa-debug-exit" -readonly CONST_QEMU_OLD_AUDIO_ARGS="-soundhw pcspk" -readonly CONST_QEMU_NEW_AUDIO_ARGS="-audiodev id=pa,driver=pa -machine pcspk-audiodev=pa" -readonly CONST_QEMU_BOOT_DEVICE="-drive driver=raw,node-name=boot,file.driver=file,file.filename=d3os.img" -readonly CONST_QEMU_GDB_PORT="1234" - -QEMU_BIOS="" -QEMU_MACHINE="${CONST_QEMU_MACHINE_PC}" -QEMU_RAM="${CONST_QEMU_DEFAULT_RAM}" -QEMU_CPU="${CONST_QEMU_CPU}" -QEMU_AUDIO_ARGS="${CONST_QEMU_NEW_AUDIO_ARGS}" -QEMU_BOOT_DEVICE="${CONST_QEMU_BOOT_DEVICE}" -QEMU_ARGS="${CONST_QEMU_ARGS}" -QEMU_DEBUG_TYPE="" - -version_lt() { - test "$(printf "%s\n" "$@" | sort -V | tr ' ' '\n' | head -n 1)" != "${2}" -} - -set_audio_parameters() { - qemu_version=$(${CONST_QEMU_BIN} --version | head -n 1 | cut -c 23-) - - if version_lt "$qemu_version" "5.0.0"; then - QEMU_AUDIO_ARGS="${CONST_QEMU_OLD_AUDIO_ARGS}" - fi -} - -get_ovmf() { - if [ ! -f "efi/OVMF.fd" ]; then - mkdir -p "efi" - wget -O efi/OVMF.fd "${CONST_OVMF_URL}" - fi -} - -check_file() { - local file=$1 - - if [ ! -f "$file" ]; then - printf "File '%s' does not exist!\\n" "${file}" - exit 1 - fi -} - -parse_file() { - local path=$1 - - if [[ $path == *.iso ]]; then - QEMU_BOOT_DEVICE="-boot d -cdrom ${path}" - elif [[ $path == *.img ]]; then - QEMU_BOOT_DEVICE="-drive driver=raw,node-name=boot,file.driver=file,file.filename=${path}" - fi - - check_file $path -} - -parse_machine() { - local machine=$1 - - if [ "${machine}" == "pc" ]; then - QEMU_MACHINE="${CONST_QEMU_MACHINE_PC}" - elif [ "${machine}" == "pc-kvm" ]; then - QEMU_MACHINE="${CONST_QEMU_MACHINE_PC_KVM}" - else - printf "Invalid machine '%s'!\\n" "${machine}" - exit 1 - fi -} - -parse_ram() { - local memory=$1 - - QEMU_RAM="${memory}" -} - -parse_cpu() { - local cpu=$1 - - QEMU_CPU="${cpu}" -} - -parse_debug() { - local type=$1 - - if [ "${type}" == "default" ] || [ "${type}" == "background" ] || [ "${type}" == "vscode" ]; then - QEMU_DEBUG_TYPE="${type}" - else - printf "Invalid debug type '%s'!\\n" "${type}" - exit 1 - fi -} - -parse_bios() { - local bios=$1 - - QEMU_BIOS="${bios}" -} - -print_usage() { - printf "Usage: ./run.sh [OPTION...] - Available options: - -f, --file - Set the .iso or .img file, which qemu should boot (Default: d3os.img) - -m, --machine - Set the machine profile, which qemu should emulate ([pc] | [pc-kvm]) (Defualt: pc) - -r, --ram - Set the amount of ram, which qemu should use (e.g. 256, 1G, ...) (Default: 128M) - -c, --cpu - Set the CPU model, which qemu should emulate (e.g. 486, pentium, pentium2, ...) (Default: base) - -d, --debug - Enable debugging with a debug type ([default] | [vscode]) (default: Disabled) - -b, --bios - Set the BIOS file, which qemu should use (Default: Download OVMF from Ubuntu 20.04 packages) - -h, --help - Show this help message\\n" -} - -parse_args() { - while [ "${1}" != "" ]; do - local arg=$1 - local val=$2 - - case $arg in - -f | --file) - parse_file "$val" - ;; - -m | --machine) - parse_machine "$val" - ;; - -r | --ram) - parse_ram "$val" - ;; - -c | --cpu) - parse_cpu "$val" - ;; - -d | --debug) - parse_debug "$val" - ;; - -b | --bios) - parse_bios "$val" - ;; - -h | --help) - print_usage - exit 0 - ;; - *) - printf "Unknown option '%s'\\n" "${arg}" - print_usage - exit 1 - ;; - esac - shift 2 - done -} - -run_qemu() { - local command="${CONST_QEMU_BIN}" - - if [ -n "${QEMU_MACHINE}" ]; then - command="${command} -machine ${QEMU_MACHINE}" - fi - - command="${command} -m ${QEMU_RAM} -cpu ${QEMU_CPU} -bios ${QEMU_BIOS} ${QEMU_ARGS} ${QEMU_BOOT_DEVICE} ${QEMU_AUDIO_ARGS}" - - printf "Running: %s\\n" "${command}" - - if [ "${QEMU_DEBUG_TYPE}" == "default" ]; then - $command -gdb tcp::"${CONST_QEMU_GDB_PORT}" -S - elif [ "${QEMU_DEBUG_TYPE}" == "background" ]; then - $command -gdb tcp::"${CONST_QEMU_GDB_PORT}" -S & - elif [ "${QEMU_DEBUG_TYPE}" == "vscode" ]; then - echo "Debugging with VSCode..."; $command -gdb tcp::"${CONST_QEMU_GDB_PORT}" -S - else - $command - fi -} - -parse_args "$@" - -if [ -z "${QEMU_BIOS}" ]; then - QEMU_BIOS="${CONST_QEMU_BIOS_EFI}" - get_ovmf -fi - -QEMU_ARGS="${QEMU_ARGS}" -set_audio_parameters - -run_qemu