Add first syscall and migrate build script to python
Some checks failed
Build / build (push) Failing after 14s

This commit is contained in:
Mathieu Strypsteen 2024-12-24 09:18:48 +01:00
parent 76e31b5e42
commit d048817209
8 changed files with 90 additions and 61 deletions

View file

@ -5,7 +5,7 @@ jobs:
runs-on: debian-12
steps:
- name: Install dependencies
run: apt-get update && apt-get install -y clang gcc-multilib llvm mtools parted udev
run: apt-get update && apt-get install -y clang gcc-multilib llvm mtools parted python udev
- name: Install Rustup
run: curl https://sh.rustup.rs | sh -s -- -y
- name: Checkout
@ -13,7 +13,7 @@ jobs:
with:
submodules: true
- name: Build
run: . ~/.bashrc && ./build.sh
run: . ~/.bashrc && ./build.py
- name: Install cargo-deny
run: . ~/.bashrc && cargo install cargo-deny
- name: Run cargo-deny

40
build.py Executable file
View file

@ -0,0 +1,40 @@
#!/usr/bin/env python
import os
import shutil
import subprocess
def run_command(cmd, cwd=None):
subprocess.run(cmd, shell=True, check=True, cwd=cwd)
def main():
target = os.environ.get("OS_TARGET", "release")
if os.path.exists("img"):
shutil.rmtree("img")
os.makedirs("img/boot/efi/boot")
run_command("make -j4", cwd="lib/acpica-build")
components = ["init", "kernel", "loader"]
for component in components:
cargo_cmd = f'cargo build {"--release" if target == "release" else ""}'
run_command(cargo_cmd, cwd=component)
loader_path = f"target/x86_64-unknown-uefi/{target}/loader.efi"
shutil.copy(loader_path, "img/boot/efi/boot/bootx64.efi")
os.chdir("img")
run_command("dd if=/dev/zero of=boot.img bs=1M count=16 status=none")
run_command("mformat -i boot.img")
run_command("mcopy -si boot.img boot/* ::")
run_command("dd if=/dev/zero of=os.img bs=1M count=32 status=none")
run_command("parted -s os.img mklabel gpt")
run_command("parted -s os.img mkpart primary fat32 2048s 100%")
run_command("parted -s os.img set 1 esp on")
run_command("dd if=boot.img of=os.img bs=1M seek=1 conv=notrunc status=none")
if __name__ == "__main__":
main()

View file

@ -1,36 +0,0 @@
#!/bin/bash
set -euo pipefail
target=${OS_TARGET:-release}
rm -rf img
mkdir -p img/boot/efi/boot
cd lib/acpica-build
make -j4
cd ../../init
if [ "$target" = "release" ]; then
cargo build --release
else
cargo build
fi
cd ../kernel
if [ "$target" = "release" ]; then
cargo build --release
else
cargo build
fi
cd ../loader
if [ "$target" = "release" ]; then
cargo build --release
else
cargo build
fi
cd ..
cp target/x86_64-unknown-uefi/$target/loader.efi img/boot/efi/boot/bootx64.efi
cd img
dd if=/dev/zero of=boot.img bs=1M count=16 status=none
mformat -i boot.img
mcopy -si boot.img boot/* ::
dd if=/dev/zero of=os.img bs=1M count=32 status=none
parted -s os.img mklabel gpt
parted -s os.img mkpart primary fat32 2048s 100%
parted -s os.img set 1 esp on
dd if=boot.img of=os.img bs=1M seek=1 conv=notrunc status=none

View file

@ -4,7 +4,7 @@ use core::{
};
use kernel_common::instructions::hlt;
use log::warn;
use log::{debug, warn};
use crate::{
sys::{
@ -12,7 +12,7 @@ use crate::{
locks::Spinlock,
scheduler::scheduler,
sync::{IN_ISR_HANDLER, LOCKS_HELD},
task::terminate_current_task,
task::{TaskState, CURRENT_TASKS},
},
BROADCASTED_PANIC,
};
@ -113,8 +113,8 @@ extern "C" fn isr_handler(state: &mut ISRState) {
IN_ISR_HANDLER[lapic_id].store(true, Ordering::SeqCst);
if state.isr < 32 {
if state.cs == 0x23 && state.isr != 2 && state.isr != 8 && state.isr != 18 {
warn!("Exception in usermode: {}", EXCEPTIONS[state.isr as usize]);
terminate_current_task();
debug!("Exception in usermode: {}", EXCEPTIONS[state.isr as usize]);
CURRENT_TASKS.lock()[get_current_lapic_id()].as_mut().unwrap().task_state = TaskState::Terminated;
IN_ISR_HANDLER[lapic_id].store(false, Ordering::SeqCst);
unsafe {
asm!("int $254");

View file

@ -8,26 +8,19 @@ syscall:
swapgs
sti
push %r11
push %r10
push %r9
push %r8
push %rsi
push %rdi
push %rdx
push %rcx
push %rax
mov %r10, %rcx
call syscall_handler
pop %rax
pop %rcx
pop %rdx
pop %rdi
pop %rsi
pop %r8
pop %r9
pop %r10
pop %r11
xor %rdx, %rdx
xor %rdi, %rdi
xor %rsi, %rsi
xor %r8, %r8
xor %r9, %r9
xor %r10, %r10
cli
swapgs
mov %gs:8, %rsp

View file

@ -1,2 +1,34 @@
use log::debug;
use super::task::terminate_current_task;
struct SyscallArgs {
_arg1: usize,
_arg2: usize,
_arg3: usize,
_arg4: usize,
_arg5: usize,
}
const SYSCALL_TABLE: [fn(SyscallArgs) -> usize; 1] = [syscall_get_kernel_version];
fn syscall_get_kernel_version(_args: SyscallArgs) -> usize {
0
}
#[no_mangle]
extern "C" fn syscall_handler() {}
extern "C" fn syscall_handler(syscall: u64, arg1: u64, arg2: u64, arg3: u64, arg4: u64, arg5: u64) -> u64 {
if syscall as usize >= SYSCALL_TABLE.len() {
debug!("Process requested invalid syscall");
terminate_current_task();
}
let args = SyscallArgs {
_arg1: arg1 as usize,
_arg2: arg2 as usize,
_arg3: arg3 as usize,
_arg4: arg4 as usize,
_arg5: arg5 as usize,
};
let result = SYSCALL_TABLE[syscall as usize](args);
result as u64
}

View file

@ -145,8 +145,10 @@ fn create_idle_task() {
IDLE_TASKS.lock().push(idle_task);
}
}
pub fn terminate_current_task() {
pub fn terminate_current_task() -> ! {
CURRENT_TASKS.lock()[get_current_lapic_id()].as_mut().unwrap().task_state = TaskState::Terminated;
yield_task();
panic!("Failed to terminate task");
}
extern "C" fn task_entry() -> ! {
let func;
@ -156,8 +158,6 @@ extern "C" fn task_entry() -> ! {
}
func();
terminate_current_task();
yield_task();
panic!("Failed to terminate task");
}
fn idle_main() {
while !ALL_APS_STARTED.load(Ordering::SeqCst) {

View file

@ -1,5 +1,5 @@
#!/bin/bash
# shellcheck disable=SC2068
set -euo pipefail
./build.sh
./build.py
qemu-system-x86_64 -M q35 -accel kvm -cpu qemu64,rdrand,smap,smep,umip -smp 4 -m 256M -L /usr/share/OVMF -bios OVMF_CODE.fd -drive file=img/os.img,format=raw $@