From 5b491989daff79231fdda177d3ba9ac1cee3b017 Mon Sep 17 00:00:00 2001 From: Mathieu Strypsteen Date: Fri, 20 Dec 2024 22:50:51 +0100 Subject: [PATCH] Add process spawning --- Cargo.lock | 9 +- Cargo.toml | 2 +- build.sh | 8 +- init/.cargo/config.toml | 3 + init/Cargo.toml | 7 + init/src/main.rs | 14 ++ kernel/Cargo.toml | 1 + kernel/src/cpu/{smp.rs => cpu.rs} | 11 +- kernel/src/cpu/idt.rs | 272 ++---------------------------- kernel/src/cpu/isr.s | 8 +- kernel/src/cpu/mod.rs | 2 +- kernel/src/cpu/paging.rs | 46 +++-- kernel/src/main.rs | 10 +- kernel/src/misc/elf.rs | 61 +++++++ kernel/src/misc/mod.rs | 1 + kernel/src/sys/hpet.rs | 4 +- kernel/src/sys/process.rs | 32 +++- kernel/src/sys/scheduler.rs | 4 +- kernel/src/sys/task.rs | 17 +- 19 files changed, 222 insertions(+), 290 deletions(-) create mode 100644 init/.cargo/config.toml create mode 100644 init/Cargo.toml create mode 100644 init/src/main.rs rename kernel/src/cpu/{smp.rs => cpu.rs} (80%) create mode 100644 kernel/src/misc/elf.rs diff --git a/Cargo.lock b/Cargo.lock index 7d48845..b5b8fd0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -194,6 +194,10 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "init" +version = "0.0.1" + [[package]] name = "itertools" version = "0.13.0" @@ -212,6 +216,7 @@ dependencies = [ "bitfield", "bitvec", "buddy_system_allocator", + "elf", "embedded-graphics", "kernel-common", "lock_api", @@ -228,9 +233,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.168" +version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" [[package]] name = "libloading" diff --git a/Cargo.toml b/Cargo.toml index 5d39115..ef17229 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [workspace] resolver = "2" -members = ["lib/acpica-rs", "lib/kernel-common", "loader", "kernel"] +members = ["lib/acpica-rs", "lib/kernel-common", "loader", "kernel", "init"] [profile.release] lto = true diff --git a/build.sh b/build.sh index 64ac156..bbe5338 100755 --- a/build.sh +++ b/build.sh @@ -5,7 +5,13 @@ rm -rf img mkdir -p img/boot/efi/boot cd lib/acpica-build make -j4 -cd ../../kernel +cd ../../init +if [ "$target" = "release" ]; then + cargo build --release +else + cargo build +fi +cd ../kernel if [ "$target" = "release" ]; then cargo build --release else diff --git a/init/.cargo/config.toml b/init/.cargo/config.toml new file mode 100644 index 0000000..2eddc64 --- /dev/null +++ b/init/.cargo/config.toml @@ -0,0 +1,3 @@ +[build] +target = "x86_64-unknown-none" +rustflags = ["-C", "link-arg=-no-pie"] diff --git a/init/Cargo.toml b/init/Cargo.toml new file mode 100644 index 0000000..6dfa817 --- /dev/null +++ b/init/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "init" +version = "0.0.1" +edition = "2021" +license = "Unlicense" + +[dependencies] diff --git a/init/src/main.rs b/init/src/main.rs new file mode 100644 index 0000000..378f073 --- /dev/null +++ b/init/src/main.rs @@ -0,0 +1,14 @@ +#![no_std] +#![no_main] + +use core::panic::PanicInfo; + +#[no_mangle] +extern "C" fn _start() -> ! { + loop {} +} + +#[panic_handler] +fn panic(_info: &PanicInfo) -> ! { + loop {} +} diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index d7d97c9..300910b 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -10,6 +10,7 @@ acpica-rs = {path = "../lib/acpica-rs"} bitfield = "0.17.0" bitvec = {version = "1.0.1", default-features = false, features = ["alloc", "atomic"]} buddy_system_allocator = "0.11.0" +elf = {version = "0.7.4", default-features = false} embedded-graphics = "0.8.1" kernel-common = {path = "../lib/kernel-common"} lock_api = "0.4.12" diff --git a/kernel/src/cpu/smp.rs b/kernel/src/cpu/cpu.rs similarity index 80% rename from kernel/src/cpu/smp.rs rename to kernel/src/cpu/cpu.rs index b84fc39..5cf4dbb 100644 --- a/kernel/src/cpu/smp.rs +++ b/kernel/src/cpu/cpu.rs @@ -24,10 +24,19 @@ extern "C" fn ap_main() -> ! { yield_task(); panic!("Yielding to idle task failed"); } - pub fn set_cpu_flags() { unsafe { // SMAP and SMEP asm!("mov rax, cr4; bts rax, 20; bts rax, 21; mov cr4, rax", out("rax") _); } } +pub fn enable_user_memory_access() { + unsafe { + asm!("stac"); + } +} +pub fn disable_user_memory_access() { + unsafe { + asm!("clac"); + } +} diff --git a/kernel/src/cpu/idt.rs b/kernel/src/cpu/idt.rs index 1d2a7a4..6185dc7 100644 --- a/kernel/src/cpu/idt.rs +++ b/kernel/src/cpu/idt.rs @@ -307,262 +307,22 @@ pub fn setup_idt() { unsafe { asm!("lidt [{}]", in(reg) idt_descriptor); } - set_address(&mut idt.entries[0], isr0); - set_address(&mut idt.entries[1], isr1); - set_address(&mut idt.entries[2], isr2); + let function_table: [unsafe extern "C" fn(); 256] = [ + isr0, isr1, isr2, isr3, isr4, isr5, isr6, isr7, isr8, isr9, isr10, isr11, isr12, isr13, isr14, isr15, isr16, isr17, isr18, isr19, isr20, isr21, isr22, isr23, isr24, isr25, isr26, isr27, + isr28, isr29, isr30, isr31, isr32, isr33, isr34, isr35, isr36, isr37, isr38, isr39, isr40, isr41, isr42, isr43, isr44, isr45, isr46, isr47, isr48, isr49, isr50, isr51, isr52, isr53, isr54, + isr55, isr56, isr57, isr58, isr59, isr60, isr61, isr62, isr63, isr64, isr65, isr66, isr67, isr68, isr69, isr70, isr71, isr72, isr73, isr74, isr75, isr76, isr77, isr78, isr79, isr80, isr81, + isr82, isr83, isr84, isr85, isr86, isr87, isr88, isr89, isr90, isr91, isr92, isr93, isr94, isr95, isr96, isr97, isr98, isr99, isr100, isr101, isr102, isr103, isr104, isr105, isr106, isr107, + isr108, isr109, isr110, isr111, isr112, isr113, isr114, isr115, isr116, isr117, isr118, isr119, isr120, isr121, isr122, isr123, isr124, isr125, isr126, isr127, isr128, isr129, isr130, isr131, + isr132, isr133, isr134, isr135, isr136, isr137, isr138, isr139, isr140, isr141, isr142, isr143, isr144, isr145, isr146, isr147, isr148, isr149, isr150, isr151, isr152, isr153, isr154, isr155, + isr156, isr157, isr158, isr159, isr160, isr161, isr162, isr163, isr164, isr165, isr166, isr167, isr168, isr169, isr170, isr171, isr172, isr173, isr174, isr175, isr176, isr177, isr178, isr179, + isr180, isr181, isr182, isr183, isr184, isr185, isr186, isr187, isr188, isr189, isr190, isr191, isr192, isr193, isr194, isr195, isr196, isr197, isr198, isr199, isr200, isr201, isr202, isr203, + isr204, isr205, isr206, isr207, isr208, isr209, isr210, isr211, isr212, isr213, isr214, isr215, isr216, isr217, isr218, isr219, isr220, isr221, isr222, isr223, isr224, isr225, isr226, isr227, + isr228, isr229, isr230, isr231, isr232, isr233, isr234, isr235, isr236, isr237, isr238, isr239, isr240, isr241, isr242, isr243, isr244, isr245, isr246, isr247, isr248, isr249, isr250, isr251, + isr252, isr253, isr254, isr255, + ]; + for i in 0..256 { + set_address(&mut idt.entries[i], function_table[i]); + } idt.entries[2].ist = 1; // NMI - set_address(&mut idt.entries[3], isr3); - set_address(&mut idt.entries[4], isr4); - set_address(&mut idt.entries[5], isr5); - set_address(&mut idt.entries[6], isr6); - set_address(&mut idt.entries[7], isr7); - set_address(&mut idt.entries[8], isr8); idt.entries[8].ist = 2; // Double fault - set_address(&mut idt.entries[9], isr9); - set_address(&mut idt.entries[10], isr10); - set_address(&mut idt.entries[11], isr11); - set_address(&mut idt.entries[12], isr12); - set_address(&mut idt.entries[13], isr13); - set_address(&mut idt.entries[14], isr14); - set_address(&mut idt.entries[15], isr15); - set_address(&mut idt.entries[16], isr16); - set_address(&mut idt.entries[17], isr17); - set_address(&mut idt.entries[18], isr18); - set_address(&mut idt.entries[19], isr19); - set_address(&mut idt.entries[20], isr20); - set_address(&mut idt.entries[21], isr21); - set_address(&mut idt.entries[22], isr22); - set_address(&mut idt.entries[23], isr23); - set_address(&mut idt.entries[24], isr24); - set_address(&mut idt.entries[25], isr25); - set_address(&mut idt.entries[26], isr26); - set_address(&mut idt.entries[27], isr27); - set_address(&mut idt.entries[28], isr28); - set_address(&mut idt.entries[29], isr29); - set_address(&mut idt.entries[30], isr30); - set_address(&mut idt.entries[31], isr31); - set_address(&mut idt.entries[32], isr32); - set_address(&mut idt.entries[33], isr33); - set_address(&mut idt.entries[34], isr34); - set_address(&mut idt.entries[35], isr35); - set_address(&mut idt.entries[36], isr36); - set_address(&mut idt.entries[37], isr37); - set_address(&mut idt.entries[38], isr38); - set_address(&mut idt.entries[39], isr39); - set_address(&mut idt.entries[40], isr40); - set_address(&mut idt.entries[41], isr41); - set_address(&mut idt.entries[42], isr42); - set_address(&mut idt.entries[43], isr43); - set_address(&mut idt.entries[44], isr44); - set_address(&mut idt.entries[45], isr45); - set_address(&mut idt.entries[46], isr46); - set_address(&mut idt.entries[47], isr47); - set_address(&mut idt.entries[48], isr48); - set_address(&mut idt.entries[49], isr49); - set_address(&mut idt.entries[50], isr50); - set_address(&mut idt.entries[51], isr51); - set_address(&mut idt.entries[52], isr52); - set_address(&mut idt.entries[53], isr53); - set_address(&mut idt.entries[54], isr54); - set_address(&mut idt.entries[55], isr55); - set_address(&mut idt.entries[56], isr56); - set_address(&mut idt.entries[57], isr57); - set_address(&mut idt.entries[58], isr58); - set_address(&mut idt.entries[59], isr59); - set_address(&mut idt.entries[60], isr60); - set_address(&mut idt.entries[61], isr61); - set_address(&mut idt.entries[62], isr62); - set_address(&mut idt.entries[63], isr63); - set_address(&mut idt.entries[64], isr64); - set_address(&mut idt.entries[65], isr65); - set_address(&mut idt.entries[66], isr66); - set_address(&mut idt.entries[67], isr67); - set_address(&mut idt.entries[68], isr68); - set_address(&mut idt.entries[69], isr69); - set_address(&mut idt.entries[70], isr70); - set_address(&mut idt.entries[71], isr71); - set_address(&mut idt.entries[72], isr72); - set_address(&mut idt.entries[73], isr73); - set_address(&mut idt.entries[74], isr74); - set_address(&mut idt.entries[75], isr75); - set_address(&mut idt.entries[76], isr76); - set_address(&mut idt.entries[77], isr77); - set_address(&mut idt.entries[78], isr78); - set_address(&mut idt.entries[79], isr79); - set_address(&mut idt.entries[80], isr80); - set_address(&mut idt.entries[81], isr81); - set_address(&mut idt.entries[82], isr82); - set_address(&mut idt.entries[83], isr83); - set_address(&mut idt.entries[84], isr84); - set_address(&mut idt.entries[85], isr85); - set_address(&mut idt.entries[86], isr86); - set_address(&mut idt.entries[87], isr87); - set_address(&mut idt.entries[88], isr88); - set_address(&mut idt.entries[89], isr89); - set_address(&mut idt.entries[90], isr90); - set_address(&mut idt.entries[91], isr91); - set_address(&mut idt.entries[92], isr92); - set_address(&mut idt.entries[93], isr93); - set_address(&mut idt.entries[94], isr94); - set_address(&mut idt.entries[95], isr95); - set_address(&mut idt.entries[96], isr96); - set_address(&mut idt.entries[97], isr97); - set_address(&mut idt.entries[98], isr98); - set_address(&mut idt.entries[99], isr99); - set_address(&mut idt.entries[100], isr100); - set_address(&mut idt.entries[101], isr101); - set_address(&mut idt.entries[102], isr102); - set_address(&mut idt.entries[103], isr103); - set_address(&mut idt.entries[104], isr104); - set_address(&mut idt.entries[105], isr105); - set_address(&mut idt.entries[106], isr106); - set_address(&mut idt.entries[107], isr107); - set_address(&mut idt.entries[108], isr108); - set_address(&mut idt.entries[109], isr109); - set_address(&mut idt.entries[110], isr110); - set_address(&mut idt.entries[111], isr111); - set_address(&mut idt.entries[112], isr112); - set_address(&mut idt.entries[113], isr113); - set_address(&mut idt.entries[114], isr114); - set_address(&mut idt.entries[115], isr115); - set_address(&mut idt.entries[116], isr116); - set_address(&mut idt.entries[117], isr117); - set_address(&mut idt.entries[118], isr118); - set_address(&mut idt.entries[119], isr119); - set_address(&mut idt.entries[120], isr120); - set_address(&mut idt.entries[121], isr121); - set_address(&mut idt.entries[122], isr122); - set_address(&mut idt.entries[123], isr123); - set_address(&mut idt.entries[124], isr124); - set_address(&mut idt.entries[125], isr125); - set_address(&mut idt.entries[126], isr126); - set_address(&mut idt.entries[127], isr127); - set_address(&mut idt.entries[128], isr128); - set_address(&mut idt.entries[129], isr129); - set_address(&mut idt.entries[130], isr130); - set_address(&mut idt.entries[131], isr131); - set_address(&mut idt.entries[132], isr132); - set_address(&mut idt.entries[133], isr133); - set_address(&mut idt.entries[134], isr134); - set_address(&mut idt.entries[135], isr135); - set_address(&mut idt.entries[136], isr136); - set_address(&mut idt.entries[137], isr137); - set_address(&mut idt.entries[138], isr138); - set_address(&mut idt.entries[139], isr139); - set_address(&mut idt.entries[140], isr140); - set_address(&mut idt.entries[141], isr141); - set_address(&mut idt.entries[142], isr142); - set_address(&mut idt.entries[143], isr143); - set_address(&mut idt.entries[144], isr144); - set_address(&mut idt.entries[145], isr145); - set_address(&mut idt.entries[146], isr146); - set_address(&mut idt.entries[147], isr147); - set_address(&mut idt.entries[148], isr148); - set_address(&mut idt.entries[149], isr149); - set_address(&mut idt.entries[150], isr150); - set_address(&mut idt.entries[151], isr151); - set_address(&mut idt.entries[152], isr152); - set_address(&mut idt.entries[153], isr153); - set_address(&mut idt.entries[154], isr154); - set_address(&mut idt.entries[155], isr155); - set_address(&mut idt.entries[156], isr156); - set_address(&mut idt.entries[157], isr157); - set_address(&mut idt.entries[158], isr158); - set_address(&mut idt.entries[159], isr159); - set_address(&mut idt.entries[160], isr160); - set_address(&mut idt.entries[161], isr161); - set_address(&mut idt.entries[162], isr162); - set_address(&mut idt.entries[163], isr163); - set_address(&mut idt.entries[164], isr164); - set_address(&mut idt.entries[165], isr165); - set_address(&mut idt.entries[166], isr166); - set_address(&mut idt.entries[167], isr167); - set_address(&mut idt.entries[168], isr168); - set_address(&mut idt.entries[169], isr169); - set_address(&mut idt.entries[170], isr170); - set_address(&mut idt.entries[171], isr171); - set_address(&mut idt.entries[172], isr172); - set_address(&mut idt.entries[173], isr173); - set_address(&mut idt.entries[174], isr174); - set_address(&mut idt.entries[175], isr175); - set_address(&mut idt.entries[176], isr176); - set_address(&mut idt.entries[177], isr177); - set_address(&mut idt.entries[178], isr178); - set_address(&mut idt.entries[179], isr179); - set_address(&mut idt.entries[180], isr180); - set_address(&mut idt.entries[181], isr181); - set_address(&mut idt.entries[182], isr182); - set_address(&mut idt.entries[183], isr183); - set_address(&mut idt.entries[184], isr184); - set_address(&mut idt.entries[185], isr185); - set_address(&mut idt.entries[186], isr186); - set_address(&mut idt.entries[187], isr187); - set_address(&mut idt.entries[188], isr188); - set_address(&mut idt.entries[189], isr189); - set_address(&mut idt.entries[190], isr190); - set_address(&mut idt.entries[191], isr191); - set_address(&mut idt.entries[192], isr192); - set_address(&mut idt.entries[193], isr193); - set_address(&mut idt.entries[194], isr194); - set_address(&mut idt.entries[195], isr195); - set_address(&mut idt.entries[196], isr196); - set_address(&mut idt.entries[197], isr197); - set_address(&mut idt.entries[198], isr198); - set_address(&mut idt.entries[199], isr199); - set_address(&mut idt.entries[200], isr200); - set_address(&mut idt.entries[201], isr201); - set_address(&mut idt.entries[202], isr202); - set_address(&mut idt.entries[203], isr203); - set_address(&mut idt.entries[204], isr204); - set_address(&mut idt.entries[205], isr205); - set_address(&mut idt.entries[206], isr206); - set_address(&mut idt.entries[207], isr207); - set_address(&mut idt.entries[208], isr208); - set_address(&mut idt.entries[209], isr209); - set_address(&mut idt.entries[210], isr210); - set_address(&mut idt.entries[211], isr211); - set_address(&mut idt.entries[212], isr212); - set_address(&mut idt.entries[213], isr213); - set_address(&mut idt.entries[214], isr214); - set_address(&mut idt.entries[215], isr215); - set_address(&mut idt.entries[216], isr216); - set_address(&mut idt.entries[217], isr217); - set_address(&mut idt.entries[218], isr218); - set_address(&mut idt.entries[219], isr219); - set_address(&mut idt.entries[220], isr220); - set_address(&mut idt.entries[221], isr221); - set_address(&mut idt.entries[222], isr222); - set_address(&mut idt.entries[223], isr223); - set_address(&mut idt.entries[224], isr224); - set_address(&mut idt.entries[225], isr225); - set_address(&mut idt.entries[226], isr226); - set_address(&mut idt.entries[227], isr227); - set_address(&mut idt.entries[228], isr228); - set_address(&mut idt.entries[229], isr229); - set_address(&mut idt.entries[230], isr230); - set_address(&mut idt.entries[231], isr231); - set_address(&mut idt.entries[232], isr232); - set_address(&mut idt.entries[233], isr233); - set_address(&mut idt.entries[234], isr234); - set_address(&mut idt.entries[235], isr235); - set_address(&mut idt.entries[236], isr236); - set_address(&mut idt.entries[237], isr237); - set_address(&mut idt.entries[238], isr238); - set_address(&mut idt.entries[239], isr239); - set_address(&mut idt.entries[240], isr240); - set_address(&mut idt.entries[241], isr241); - set_address(&mut idt.entries[242], isr242); - set_address(&mut idt.entries[243], isr243); - set_address(&mut idt.entries[244], isr244); - set_address(&mut idt.entries[245], isr245); - set_address(&mut idt.entries[246], isr246); - set_address(&mut idt.entries[247], isr247); - set_address(&mut idt.entries[248], isr248); - set_address(&mut idt.entries[249], isr249); - set_address(&mut idt.entries[250], isr250); - set_address(&mut idt.entries[251], isr251); - set_address(&mut idt.entries[252], isr252); // Invalidate TLB - set_address(&mut idt.entries[253], isr253); // SCI - set_address(&mut idt.entries[254], isr254); // Scheduler - set_address(&mut idt.entries[255], isr255); // Spurious interrupt } diff --git a/kernel/src/cpu/isr.s b/kernel/src/cpu/isr.s index 78d270f..3d84804 100644 --- a/kernel/src/cpu/isr.s +++ b/kernel/src/cpu/isr.s @@ -305,7 +305,7 @@ isr 248 isr 249 isr 250 isr 251 -isr 252 -isr 253 -isr 254 -isr 255 +isr 252 // Invalidate TLB +isr 253 // SCI +isr 254 // Scheduler +isr 255 // Spurious interrupt diff --git a/kernel/src/cpu/mod.rs b/kernel/src/cpu/mod.rs index 3ed47e8..4852df1 100644 --- a/kernel/src/cpu/mod.rs +++ b/kernel/src/cpu/mod.rs @@ -1,5 +1,5 @@ +pub mod cpu; pub mod gdt; pub mod idt; pub mod isr; pub mod paging; -pub mod smp; diff --git a/kernel/src/cpu/paging.rs b/kernel/src/cpu/paging.rs index e03771c..3c35368 100644 --- a/kernel/src/cpu/paging.rs +++ b/kernel/src/cpu/paging.rs @@ -78,7 +78,7 @@ impl AddressSpace { } panic!("No free range found"); } - fn map(&mut self, virt: u64, phys: u64, user: bool, write: bool, exec: bool, cache_disable: bool) { + fn map(&mut self, virt: u64, phys: u64, user: bool, write: bool, exec: bool, cache_disable: bool, only_flags: bool) { assert!(virt >= 0x1000, "First page shouldn't be mapped"); assert!(!write || !exec || virt == 0x1000); { @@ -97,7 +97,11 @@ impl AddressSpace { let directory = get_table_entry(pdpt, pdpt_i); let table = get_table_entry(directory, directory_i); let should_invalidate = table.entries_phys[table_i].present() == 1; - table.entries_phys[table_i].set_address(phys / 0x1000); + if !only_flags { + table.entries_phys[table_i].set_address(phys / 0x1000); + } else { + assert_eq!(table.entries_phys[table_i].present(), 1); + } table.entries_phys[table_i].set_user(user as u64); table.entries_phys[table_i].set_write(write as u64); table.entries_phys[table_i].set_execute_disable(!exec as u64); @@ -121,7 +125,22 @@ impl AddressSpace { assert_eq!(phys_start % 0x1000, 0); assert_eq!(size % 0x1000, 0); for i in 0..size / 0x1000 { - self.map(virt_start + i * 0x1000, phys_start + i * 0x1000, user, write, exec, cache_disable); + self.map(virt_start + i * 0x1000, phys_start + i * 0x1000, user, write, exec, cache_disable, false); + } + } + pub unsafe fn allocate_range(&mut self, virt_start: u64, size: u64, user: bool, write: bool, exec: bool) { + assert_eq!(virt_start % 0x1000, 0); + assert_eq!(size % 0x1000, 0); + for i in 0..size / 0x1000 { + let frame = get_free_frame(); + self.map(virt_start + i * 0x1000, frame * 0x1000, user, write, exec, false, false); + } + } + pub unsafe fn update_flags_range(&mut self, virt_start: u64, size: u64, user: bool, write: bool, exec: bool) { + assert_eq!(virt_start % 0x1000, 0); + assert_eq!(size % 0x1000, 0); + for i in 0..size / 0x1000 { + self.map(virt_start + i * 0x1000, 0, user, write, exec, false, true); } } pub unsafe fn map_physical(&mut self, phys: u64, mut size: u64, write_combining: bool) -> u64 { @@ -147,9 +166,15 @@ impl AddressSpace { } } } + pub unsafe fn switch(&self) { + let pml4_address = self.pml4.get().unwrap().as_ref() as *const PageTable as u64; + unsafe { + load_cr3(virt_to_phys(pml4_address)); + } + } } -fn _get_free_frame() -> u64 { +fn get_free_frame() -> u64 { let frames_vec = PHYSICAL_FRAMES.lock(); let frames_vec = frames_vec.get().unwrap(); for i in 0..frames_vec.len() { @@ -239,7 +264,6 @@ pub fn setup_paging(loader_struct: &LoaderStruct, phys_start: u64, heap_start: u })) .unwrap_or_else(|_| panic!()); let pml4 = address_space.pml4.get_mut().unwrap(); - let pml4_address = pml4.as_ref() as *const PageTable as u64; for i in 256..512 { get_table_entry(pml4, i); pml4.entries_phys[i].set_user(0); @@ -248,26 +272,26 @@ pub fn setup_paging(loader_struct: &LoaderStruct, phys_start: u64, heap_start: u } } for i in text_start..text_end { - address_space.map(i * 0x1000, i * 0x1000 - KERNEL_VIRT_START + phys_start, false, false, true, false); + address_space.map(i * 0x1000, i * 0x1000 - KERNEL_VIRT_START + phys_start, false, false, true, false, false); } for i in rodata_start..rodata_end { - address_space.map(i * 0x1000, i * 0x1000 - KERNEL_VIRT_START + phys_start, false, false, false, false); + address_space.map(i * 0x1000, i * 0x1000 - KERNEL_VIRT_START + phys_start, false, false, false, false, false); } for i in data_start..data_end { - address_space.map(i * 0x1000, i * 0x1000 - KERNEL_VIRT_START + phys_start, false, true, false, false); + address_space.map(i * 0x1000, i * 0x1000 - KERNEL_VIRT_START + phys_start, false, true, false, false, false); } for i in bss_start..bss_end { - address_space.map(i * 0x1000, i * 0x1000 - KERNEL_VIRT_START + phys_start, false, true, false, false); + address_space.map(i * 0x1000, i * 0x1000 - KERNEL_VIRT_START + phys_start, false, true, false, false, false); } { let mut heap_map = HEAP_PHYS_MAPPING.lock(); for i in 0..KERNEL_HEAP_INITIAL_SIZE / 0x1000 { - address_space.map(KERNEL_HEAP_START + i as u64 * 0x1000, heap_start + i as u64 * 0x1000, false, true, false, false); + address_space.map(KERNEL_HEAP_START + i as u64 * 0x1000, heap_start + i as u64 * 0x1000, false, true, false, false, false); heap_map.push(heap_start + i as u64 * 0x1000); } } unsafe { - load_cr3(virt_to_phys(pml4_address)); + address_space.switch(); } PAGING_ACTIVE.store(true, Ordering::SeqCst); } diff --git a/kernel/src/main.rs b/kernel/src/main.rs index 32cbc26..3707a0d 100644 --- a/kernel/src/main.rs +++ b/kernel/src/main.rs @@ -15,7 +15,7 @@ use acpi::AcpiTables; use acpica_rs::{AcpiEnableSubsystem, AcpiInitializeObjects, AcpiInitializeSubsystem, AcpiInitializeTables, AcpiLoadTables, ACPI_FULL_INITIALIZATION}; use alloc::format; use buddy_system_allocator::LockedHeap; -use cpu::{gdt::setup_gdt, idt::setup_idt, paging::setup_paging, smp::set_cpu_flags}; +use cpu::{cpu::set_cpu_flags, gdt::setup_gdt, idt::setup_idt, paging::setup_paging}; use kernel_common::{ instructions::{cli, hlt}, loader_struct::{FramebufferInfo, LoaderStruct, LoaderStructMemoryRegion, LOADER_STRUCT_MAGIC}, @@ -32,6 +32,7 @@ use sys::{ locks::Spinlock, madt::{parse_madt, INTERRUPTS_SETUP}, pic::disable_pic, + process::start_init, smp::{smp_broadcast_panic, start_aps}, sync::LOCKS_HELD, task::setup_multitasking, @@ -63,6 +64,12 @@ pub static BROADCASTED_PANIC: AtomicBool = AtomicBool::new(false); global_asm!(include_str!("cpu/boot.s"), options(att_syntax)); global_asm!(include_str!("cpu/trampoline.s"), options(att_syntax)); +#[cfg(debug_assertions)] +const INIT_BINARY: &[u8] = include_bytes!("../../target/x86_64-unknown-none/debug/init"); + +#[cfg(not(debug_assertions))] +const INIT_BINARY: &[u8] = include_bytes!("../../target/x86_64-unknown-none/release/init"); + #[no_mangle] extern "C" fn early_main(temp_loader_struct: *const LoaderStruct) -> ! { unsafe { @@ -104,6 +111,7 @@ fn main() { status = unsafe { AcpiInitializeObjects(ACPI_FULL_INITIALIZATION) }; assert_eq!(status, AE_OK); start_aps(); + start_init(); } #[panic_handler] fn panic(info: &PanicInfo) -> ! { diff --git a/kernel/src/misc/elf.rs b/kernel/src/misc/elf.rs new file mode 100644 index 0000000..f4c6e72 --- /dev/null +++ b/kernel/src/misc/elf.rs @@ -0,0 +1,61 @@ +use core::{mem, ptr}; + +use elf::{abi::PT_LOAD, endian::LittleEndian, ElfBytes}; +use log::info; + +use crate::{ + cpu::cpu::{disable_user_memory_access, enable_user_memory_access}, + sys::{lapic::get_current_lapic_id, task::CURRENT_TASKS}, +}; + +const USER_END: u64 = 0x800000000000; + +// TODO: Proper error handling +// TODO: Verify whether p_offset is within bounds +pub fn load_binary() { + let process; + { + let mut current_tasks = CURRENT_TASKS.lock(); + let task = current_tasks[get_current_lapic_id()].as_mut().unwrap(); + process = task.process.clone(); + } + let entry; + { + let mut process = process.lock(); + let binary = process.binary.unwrap(); + let file: ElfBytes = ElfBytes::minimal_parse(binary).unwrap(); + for i in file.segments().unwrap() { + if i.p_type != PT_LOAD { + continue; + } + let write = i.p_flags & 2 != 0; + let exec = i.p_flags & 1 != 0; + assert!(i.p_vaddr < USER_END); + assert!(i.p_vaddr + i.p_memsz < USER_END); + assert!(i.p_vaddr + i.p_memsz >= i.p_vaddr); + assert!(i.p_filesz <= i.p_memsz); + assert!(!write || !exec); + let start = i.p_vaddr / 0x1000 * 0x1000; + let end = (i.p_vaddr + i.p_memsz + 0xfff) / 0x1000 * 0x1000; + let size = end - start; + unsafe { + process.address_space.allocate_range(start, size, true, true, false); + } + enable_user_memory_access(); + unsafe { + ptr::write_bytes(i.p_vaddr as *mut u8, 0, i.p_memsz as usize); + ptr::copy(binary[i.p_offset as usize..].as_ptr(), i.p_vaddr as *mut u8, i.p_filesz as usize); + } + disable_user_memory_access(); + unsafe { + // TODO: enable user flag + process.address_space.update_flags_range(start, size, false, write, exec); + } + } + entry = file.ehdr.e_entry; + } + info!("Starting init..."); + unsafe { + (mem::transmute:: !>(entry))(); + } +} diff --git a/kernel/src/misc/mod.rs b/kernel/src/misc/mod.rs index b31dfe8..7e7f578 100644 --- a/kernel/src/misc/mod.rs +++ b/kernel/src/misc/mod.rs @@ -1,3 +1,4 @@ pub mod display; mod draw_target; +pub mod elf; pub mod wrapped_alloc; diff --git a/kernel/src/sys/hpet.rs b/kernel/src/sys/hpet.rs index f10b97e..a66283f 100644 --- a/kernel/src/sys/hpet.rs +++ b/kernel/src/sys/hpet.rs @@ -89,8 +89,8 @@ pub fn get_current_time() -> usize { pub fn sleep(us: usize) { if MULTITASKING_ENABLED.load(Ordering::SeqCst) { { - let mut _current_task = CURRENT_TASKS.lock(); - let current_task = _current_task[get_current_lapic_id()].as_mut().unwrap(); + let mut current_tasks = CURRENT_TASKS.lock(); + let current_task = current_tasks[get_current_lapic_id()].as_mut().unwrap(); current_task.sleep_until_us = get_current_time() + us; current_task.task_state = TaskState::Sleeping; } diff --git a/kernel/src/sys/process.rs b/kernel/src/sys/process.rs index aeda292..355f2ec 100644 --- a/kernel/src/sys/process.rs +++ b/kernel/src/sys/process.rs @@ -1,18 +1,21 @@ use core::cell::{LazyCell, OnceCell}; -use alloc::sync::Arc; +use alloc::{boxed::Box, sync::Arc}; +use kernel_common::paging::{PageEntry, PageTable}; -use crate::cpu::paging::AddressSpace; +use crate::{cpu::paging::AddressSpace, misc::elf::load_binary, INIT_BINARY}; -use super::locks::Spinlock; +use super::{locks::Spinlock, scheduler::SCHEDULER, task::create_task}; pub struct Process { pub address_space: AddressSpace, + pub binary: Option<&'static [u8]>, } static KERNEL_PROCESS: Spinlock>>> = Spinlock::new(LazyCell::new(|| { let process = Process { address_space: AddressSpace { pml4: OnceCell::new() }, + binary: None, }; Arc::new(Spinlock::new(process)) })); @@ -20,3 +23,26 @@ static KERNEL_PROCESS: Spinlock>>> = Spinlock::ne pub fn get_kernel_process() -> Arc> { KERNEL_PROCESS.lock().clone() } +pub fn create_process(binary: Option<&'static [u8]>) -> Arc> { + let process = Process { + address_space: AddressSpace { pml4: OnceCell::new() }, + binary, + }; + let mut pml4 = Box::new(PageTable { + entries_phys: [PageEntry(0); 512], + entries_virt: [const { None }; 512], + }); + let kernel_proc = get_kernel_process(); + let kernel_proc = kernel_proc.lock(); + let kernel_pml4 = kernel_proc.address_space.pml4.get().unwrap(); + for i in 256..512 { + pml4.entries_phys[i] = kernel_pml4.entries_phys[i]; + } + process.address_space.pml4.set(pml4).unwrap_or_else(|_| panic!()); + Arc::new(Spinlock::new(process)) +} +pub fn start_init() { + let process = create_process(Some(INIT_BINARY)); + let task = create_task(process, load_binary); + SCHEDULER.lock().add_task(task); +} diff --git a/kernel/src/sys/scheduler.rs b/kernel/src/sys/scheduler.rs index 244efc5..ebfa6e1 100644 --- a/kernel/src/sys/scheduler.rs +++ b/kernel/src/sys/scheduler.rs @@ -46,8 +46,8 @@ pub fn scheduler(state: &mut ISRState) { } let mut switch_idle = false; { - let _current_task = CURRENT_TASKS.lock(); - let current_task = _current_task[get_current_lapic_id()].as_ref(); + let current_tasks = CURRENT_TASKS.lock(); + let current_task = current_tasks[get_current_lapic_id()].as_ref(); if current_task.is_none() { switch_idle = true; } diff --git a/kernel/src/sys/task.rs b/kernel/src/sys/task.rs index 510d238..272a061 100644 --- a/kernel/src/sys/task.rs +++ b/kernel/src/sys/task.rs @@ -32,7 +32,7 @@ pub enum TaskState { pub struct Task { pub id: usize, - _process: Arc>, + pub process: Arc>, state: ISRState, _kernel_stack: Vec, initial_func: fn(), @@ -55,8 +55,8 @@ pub fn allocate_stack() -> u64 { stack.leak().as_mut_ptr() as u64 + STACK_SIZE as u64 } pub fn switch_task(current_state: &mut ISRState, new_task: Task) { - let mut _current_task = CURRENT_TASKS.lock(); - if let Some(mut current_task) = _current_task[get_current_lapic_id()].take() { + let mut current_tasks = CURRENT_TASKS.lock(); + if let Some(mut current_task) = current_tasks[get_current_lapic_id()].take() { current_task.state = *current_state; match current_task.task_state { TaskState::Ready => { @@ -69,14 +69,21 @@ pub fn switch_task(current_state: &mut ISRState, new_task: Task) { } } *current_state = new_task.state; - _current_task[get_current_lapic_id()] = Some(new_task); + { + let process = new_task.process.lock(); + unsafe { + // TODO: Only switch if needed + process.address_space.switch(); + } + } + current_tasks[get_current_lapic_id()] = Some(new_task); schedule_timer_interrupt(); } pub fn create_task(process: Arc>, func: fn()) -> Task { let stack = vec![0; STACK_SIZE]; Task { id: NEXT_TASK_ID.fetch_add(1, Ordering::SeqCst), - _process: process, + process, state: ISRState { rax: 0, rbx: 0,