Add process spawning
All checks were successful
Build / build (push) Successful in 2m47s

This commit is contained in:
Mathieu Strypsteen 2024-12-20 22:50:51 +01:00
parent 55e78f3b98
commit 5b491989da
19 changed files with 222 additions and 290 deletions

9
Cargo.lock generated
View file

@ -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"

View file

@ -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

View file

@ -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

3
init/.cargo/config.toml Normal file
View file

@ -0,0 +1,3 @@
[build]
target = "x86_64-unknown-none"
rustflags = ["-C", "link-arg=-no-pie"]

7
init/Cargo.toml Normal file
View file

@ -0,0 +1,7 @@
[package]
name = "init"
version = "0.0.1"
edition = "2021"
license = "Unlicense"
[dependencies]

14
init/src/main.rs Normal file
View file

@ -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 {}
}

View file

@ -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"

View file

@ -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");
}
}

View file

@ -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
}

View file

@ -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

View file

@ -1,5 +1,5 @@
pub mod cpu;
pub mod gdt;
pub mod idt;
pub mod isr;
pub mod paging;
pub mod smp;

View file

@ -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;
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);
}

View file

@ -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) -> ! {

61
kernel/src/misc/elf.rs Normal file
View file

@ -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<LittleEndian> = 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::<u64, extern "C" fn() -> !>(entry))();
}
}

View file

@ -1,3 +1,4 @@
pub mod display;
mod draw_target;
pub mod elf;
pub mod wrapped_alloc;

View file

@ -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;
}

View file

@ -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<LazyCell<Arc<Spinlock<Process>>>> = 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<LazyCell<Arc<Spinlock<Process>>>> = Spinlock::ne
pub fn get_kernel_process() -> Arc<Spinlock<Process>> {
KERNEL_PROCESS.lock().clone()
}
pub fn create_process(binary: Option<&'static [u8]>) -> Arc<Spinlock<Process>> {
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);
}

View file

@ -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;
}

View file

@ -32,7 +32,7 @@ pub enum TaskState {
pub struct Task {
pub id: usize,
_process: Arc<Spinlock<Process>>,
pub process: Arc<Spinlock<Process>>,
state: ISRState,
_kernel_stack: Vec<u8>,
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<Spinlock<Process>>, 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,