Add first syscall and migrate build script to python
All checks were successful
Build / build (push) Successful in 2m48s

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

View file

@ -5,7 +5,7 @@ jobs:
runs-on: debian-12 runs-on: debian-12
steps: steps:
- name: Install dependencies - 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 python3 udev
- name: Install Rustup - name: Install Rustup
run: curl https://sh.rustup.rs | sh -s -- -y run: curl https://sh.rustup.rs | sh -s -- -y
- name: Checkout - name: Checkout
@ -13,7 +13,7 @@ jobs:
with: with:
submodules: true submodules: true
- name: Build - name: Build
run: . ~/.bashrc && ./build.sh run: . ~/.bashrc && ./build.py
- name: Install cargo-deny - name: Install cargo-deny
run: . ~/.bashrc && cargo install cargo-deny run: . ~/.bashrc && cargo install cargo-deny
- name: Run cargo-deny - name: Run cargo-deny

40
build.py Executable file
View file

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

View file

@ -8,26 +8,19 @@ syscall:
swapgs swapgs
sti sti
push %r11 push %r11
push %r10
push %r9
push %r8
push %rsi
push %rdi
push %rdx
push %rcx push %rcx
push %rax mov %r10, %rcx
call syscall_handler call syscall_handler
pop %rax
pop %rcx pop %rcx
pop %rdx
pop %rdi
pop %rsi
pop %r8
pop %r9
pop %r10
pop %r11 pop %r11
xor %rdx, %rdx
xor %rdi, %rdi
xor %rsi, %rsi
xor %r8, %r8
xor %r9, %r9
xor %r10, %r10
cli cli
swapgs swapgs
mov %gs:8, %rsp 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] #[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); 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; 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() -> ! { extern "C" fn task_entry() -> ! {
let func; let func;
@ -156,8 +158,6 @@ extern "C" fn task_entry() -> ! {
} }
func(); func();
terminate_current_task(); terminate_current_task();
yield_task();
panic!("Failed to terminate task");
} }
fn idle_main() { fn idle_main() {
while !ALL_APS_STARTED.load(Ordering::SeqCst) { while !ALL_APS_STARTED.load(Ordering::SeqCst) {

View file

@ -1,5 +1,5 @@
#!/bin/bash #!/bin/bash
# shellcheck disable=SC2068 # shellcheck disable=SC2068
set -euo pipefail 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 $@ 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 $@