From add57d3803724e08843dcd3d5487c7ec3046969c Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Fri, 24 Sep 2021 18:20:48 +0200 Subject: [PATCH 01/16] Add ELF loader --- Cargo.lock | 16 ++++++++++++++++ Cargo.toml | 1 + src/sys/process.rs | 46 ++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 57 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 85f8cd51a..5a001a1ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -236,6 +236,12 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c75de51135344a4f8ed3cfe2720dc27736f7711989703a0b43aadf3753c55577" +[[package]] +name = "memchr" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + [[package]] name = "moros" version = "0.6.0" @@ -252,6 +258,7 @@ dependencies = [ "libm", "linked_list_allocator", "littlewing", + "object", "pbkdf2", "pc-keyboard", "pic8259", @@ -283,6 +290,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "object" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39f37e50073ccad23b6d09bcb5b263f4e76d3bb6038e4a3c08e52162ffa8abc2" +dependencies = [ + "memchr", +] + [[package]] name = "opaque-debug" version = "0.3.0" diff --git a/Cargo.toml b/Cargo.toml index b1808c1b9..ef9064847 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,6 +28,7 @@ lazy_static = { version = "1.4.0", features = ["spin_no_std"] } libm = "0.2.1" linked_list_allocator = "0.9.0" littlewing = { version = "0.7.0", default-features = false } +object = { version = "0.26.2", default-features = false, features = ["read"] } pbkdf2 = { version = "0.9.0", default-features = false } pc-keyboard = "0.5.1" pic8259 = "0.10.2" diff --git a/src/sys/process.rs b/src/sys/process.rs index e122bf9cc..c111af79c 100644 --- a/src/sys/process.rs +++ b/src/sys/process.rs @@ -1,3 +1,4 @@ +use crate::usr; use crate::sys::fs::{Resource, Device}; use crate::sys::console::Console; use alloc::collections::btree_map::BTreeMap; @@ -6,6 +7,7 @@ use alloc::vec; use alloc::vec::Vec; use core::sync::atomic::{AtomicUsize, Ordering}; use lazy_static::lazy_static; +use object::{Object, ObjectSection}; use spin::Mutex; const MAX_FILE_HANDLES: usize = 1024; @@ -128,11 +130,12 @@ use x86_64::structures::paging::{Page, PageTableFlags}; static STACK_ADDR: AtomicU64 = AtomicU64::new(0x600_000); static CODE_ADDR: AtomicU64 = AtomicU64::new(0x400_000); -const PAGE_SIZE: u64 = 1024 * 4; +const PAGE_SIZE: u64 = 4 * 1024; pub struct Process { stack_addr: u64, code_addr: u64, + entry: u64, } impl Process { @@ -156,16 +159,45 @@ impl Process { mapper.map_to(page, frame, flags, &mut frame_allocator).unwrap().flush(); } - unsafe { - let code_addr = code_addr as *mut u8; - for (i, op) in bin.iter().enumerate() { - core::ptr::write(code_addr.add(i), *op); + let mut entry = 0; + let code_ptr = code_addr as *mut u8; + if &bin[1..4] == b"ELF" { + // ELF binary + printk!("DEBUG: ELF detected\n"); + if let Ok(obj) = object::File::parse(bin) { + entry = obj.entry(); + printk!("DEBUG: ELF parsed\n"); + printk!("DEBUG: ELF entry: {}\n", obj.entry()); + printk!("DEBUG: ELF base: {}\n", obj.relative_address_base()); + for name in [".text", ".data", ".rodata"] { + if let Some(section) = obj.section_by_name(name) { + let addr = section.address() as usize; + let size = section.size(); + let align = section.align(); + printk!("DEBUG: ELF {} (addr: {}, size: {}, align: {})\n", name, addr, size, align); + if let Ok(data) = section.data() { + usr::hex::print_hex(data); + unsafe { + for (i, op) in data.iter().enumerate() { + core::ptr::write(code_ptr.add(addr + i), *op); + } + } + } + } + } + } + } else { + // Raw binary + unsafe { + for (i, op) in bin.iter().enumerate() { + core::ptr::write(code_ptr.add(i), *op); + } } } set_code_addr(code_addr); - Process { stack_addr, code_addr } + Process { stack_addr, code_addr, entry } } // Switch to userspace @@ -181,6 +213,8 @@ impl Process { "push rdx", "push rdi", "iretq", + "jmp [r8]", + in("r8") self.entry, in("rax") data, in("rsi") self.stack_addr, in("rdx") code, From 99ef5cf1211efb90a7279eafbabbed2beae59412 Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sat, 25 Sep 2021 08:43:00 +0200 Subject: [PATCH 02/16] Add elf reader --- src/sys/process.rs | 11 ++--------- src/usr/elf.rs | 43 +++++++++++++++++++++++++++++++++++++++++++ src/usr/find.rs | 2 +- src/usr/mod.rs | 1 + src/usr/shell.rs | 1 + 5 files changed, 48 insertions(+), 10 deletions(-) create mode 100644 src/usr/elf.rs diff --git a/src/sys/process.rs b/src/sys/process.rs index c111af79c..bc6d61b4d 100644 --- a/src/sys/process.rs +++ b/src/sys/process.rs @@ -1,4 +1,3 @@ -use crate::usr; use crate::sys::fs::{Resource, Device}; use crate::sys::console::Console; use alloc::collections::btree_map::BTreeMap; @@ -163,20 +162,14 @@ impl Process { let code_ptr = code_addr as *mut u8; if &bin[1..4] == b"ELF" { // ELF binary - printk!("DEBUG: ELF detected\n"); if let Ok(obj) = object::File::parse(bin) { entry = obj.entry(); - printk!("DEBUG: ELF parsed\n"); - printk!("DEBUG: ELF entry: {}\n", obj.entry()); - printk!("DEBUG: ELF base: {}\n", obj.relative_address_base()); for name in [".text", ".data", ".rodata"] { if let Some(section) = obj.section_by_name(name) { let addr = section.address() as usize; - let size = section.size(); - let align = section.align(); - printk!("DEBUG: ELF {} (addr: {}, size: {}, align: {})\n", name, addr, size, align); + //let size = section.size(); + //let align = section.align(); if let Ok(data) = section.data() { - usr::hex::print_hex(data); unsafe { for (i, op) in data.iter().enumerate() { core::ptr::write(code_ptr.add(addr + i), *op); diff --git a/src/usr/elf.rs b/src/usr/elf.rs new file mode 100644 index 000000000..f58ee3c82 --- /dev/null +++ b/src/usr/elf.rs @@ -0,0 +1,43 @@ +use crate::api::console::Style; +use crate::api::fs; +use crate::usr; +use object::{Object, ObjectSection}; + +pub fn main(args: &[&str]) -> usr::shell::ExitCode { + if args.len() != 2 { + return usr::shell::ExitCode::CommandError; + } + + let color = Style::color("LightBlue"); + let reset = Style::reset(); + + let pathname = args[1]; + if let Ok(buf) = fs::read(pathname) { + let bin = buf.as_slice(); + if let Ok(obj) = object::File::parse(bin) { + println!("ELF entry address: {:#x}", obj.entry()); + for section in obj.sections() { + if let Ok(name) = section.name() { + if name.is_empty() { + continue; + } + let addr = section.address() as usize; + let size = section.size(); + let align = section.align(); + println!(); + println!("{}{}{} (addr: {:#x}, size: {}, align: {})", color, name, reset, addr, size, align); + if let Ok(data) = section.data() { + usr::hex::print_hex(data); + } + } + } + usr::shell::ExitCode::CommandSuccessful + } else { + println!("Could not parse ELF"); + usr::shell::ExitCode::CommandError + } + } else { + println!("File not found '{}'", pathname); + usr::shell::ExitCode::CommandError + } +} diff --git a/src/usr/find.rs b/src/usr/find.rs index bef495ef6..a7ff48d54 100644 --- a/src/usr/find.rs +++ b/src/usr/find.rs @@ -83,7 +83,7 @@ fn print_matching_lines(path: &str, pattern: &str, state: &mut PrintingState) { } fn print_matching_lines_in_file(path: &str, pattern: &str, state: &mut PrintingState) { - let name_color = Style::color("Cyan"); + let name_color = Style::color("LightBlue"); let line_color = Style::color("Yellow"); let match_color = Style::color("LightRed"); let reset = Style::reset(); diff --git a/src/usr/mod.rs b/src/usr/mod.rs index f80fd5e3c..92c298555 100644 --- a/src/usr/mod.rs +++ b/src/usr/mod.rs @@ -9,6 +9,7 @@ pub mod delete; pub mod dhcp; pub mod disk; pub mod editor; +pub mod elf; pub mod env; pub mod find; pub mod geotime; diff --git a/src/usr/shell.rs b/src/usr/shell.rs index b064a5c6f..7b3245b92 100644 --- a/src/usr/shell.rs +++ b/src/usr/shell.rs @@ -181,6 +181,7 @@ pub fn exec(cmd: &str) -> ExitCode { "lisp" => usr::lisp::main(&args), "chess" => usr::chess::main(&args), "beep" => usr::beep::main(&args), + "elf" => usr::elf::main(&args), cmd => { if let Ok(process) = api::process::create(cmd) { process.switch(); From 4745e6c406964738526164aacd6555a886907351 Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sat, 25 Sep 2021 09:28:05 +0200 Subject: [PATCH 03/16] Fix jump to entry point --- src/sys/process.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sys/process.rs b/src/sys/process.rs index bc6d61b4d..44f26ab62 100644 --- a/src/sys/process.rs +++ b/src/sys/process.rs @@ -205,13 +205,13 @@ impl Process { "push 0x200", "push rdx", "push rdi", + "jmp r8", "iretq", - "jmp [r8]", - in("r8") self.entry, in("rax") data, in("rsi") self.stack_addr, in("rdx") code, in("rdi") self.code_addr, + in("r8") self.code_addr + self.entry, ); } } From 2c0dc7d2b5e686b0a2bbe75a7bfc5532d517e063 Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sat, 25 Sep 2021 13:44:13 +0200 Subject: [PATCH 04/16] Update mapping code --- src/sys/allocator.rs | 2 +- src/sys/process.rs | 27 +++++++++++++++++++-------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/sys/allocator.rs b/src/sys/allocator.rs index 804a3f077..904b8555c 100644 --- a/src/sys/allocator.rs +++ b/src/sys/allocator.rs @@ -10,7 +10,7 @@ use x86_64::structures::paging::mapper::MapToError; use x86_64::structures::paging::{FrameAllocator, Mapper, Page, PageTableFlags, Size4KiB}; use x86_64::VirtAddr; -pub const HEAP_START: usize = 0x_4444_4444_0000; +pub const HEAP_START: usize = 0x4444_4444_0000; pub const HEAP_SIZE: usize = 16 << 20; // MB #[global_allocator] diff --git a/src/sys/process.rs b/src/sys/process.rs index 44f26ab62..abdc76f61 100644 --- a/src/sys/process.rs +++ b/src/sys/process.rs @@ -127,8 +127,8 @@ use x86_64::instructions::interrupts; use x86_64::structures::paging::{Mapper, FrameAllocator}; use x86_64::structures::paging::{Page, PageTableFlags}; -static STACK_ADDR: AtomicU64 = AtomicU64::new(0x600_000); -static CODE_ADDR: AtomicU64 = AtomicU64::new(0x400_000); +static CODE_ADDR: AtomicU64 = AtomicU64::new(0x40_0000); +static STACK_ADDR: AtomicU64 = AtomicU64::new(0x80_0000); const PAGE_SIZE: u64 = 4 * 1024; pub struct Process { @@ -153,9 +153,13 @@ impl Process { let code_addr = CODE_ADDR.fetch_add(PAGE_SIZE, Ordering::SeqCst); let frame = frame_allocator.allocate_frame().unwrap(); - let page = Page::containing_address(VirtAddr::new(code_addr)); - unsafe { - mapper.map_to(page, frame, flags, &mut frame_allocator).unwrap().flush(); + for i in 0..1024 { + let addr = code_addr + i * PAGE_SIZE; + //printk!("DEBUG: map {:#x} (virt: {:#x})\n", addr, i * PAGE_SIZE); + let page = Page::containing_address(VirtAddr::new(addr)); + unsafe { + mapper.map_to(page, frame, flags, &mut frame_allocator).unwrap().flush(); + } } let mut entry = 0; @@ -164,15 +168,22 @@ impl Process { // ELF binary if let Ok(obj) = object::File::parse(bin) { entry = obj.entry(); - for name in [".text", ".data", ".rodata"] { - if let Some(section) = obj.section_by_name(name) { + for section in obj.sections() { + use crate::api::syscall::sleep; + if let Ok(name) = section.name() { let addr = section.address() as usize; //let size = section.size(); //let align = section.align(); + if name.is_empty() || addr == 0 { + continue; + } if let Ok(data) = section.data() { + //printk!("DEBUG: {}\n", name); unsafe { for (i, op) in data.iter().enumerate() { - core::ptr::write(code_ptr.add(addr + i), *op); + let ptr = code_ptr.add(addr + i); + //printk!("DEBUG: ptr {:#x} (virt: {:#x})\n", ptr as usize, addr + i); + core::ptr::write(ptr, *op); } } } From f1a836ff08e3e26d1c42302f629aabf086deefca Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sat, 25 Sep 2021 23:46:11 +0200 Subject: [PATCH 05/16] Update kernel data segment in GDT --- src/sys/gdt.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/sys/gdt.rs b/src/sys/gdt.rs index 08582b5b6..625f864b4 100644 --- a/src/sys/gdt.rs +++ b/src/sys/gdt.rs @@ -2,7 +2,7 @@ use lazy_static::lazy_static; use x86_64::VirtAddr; use x86_64::instructions::segmentation::{CS, DS, Segment}; use x86_64::instructions::tables::load_tss; -use x86_64::structures::gdt::{Descriptor, DescriptorFlags, GlobalDescriptorTable, SegmentSelector}; +use x86_64::structures::gdt::{Descriptor, GlobalDescriptorTable, SegmentSelector}; use x86_64::structures::tss::TaskStateSegment; const STACK_SIZE: usize = 8192; @@ -36,22 +36,21 @@ lazy_static! { lazy_static! { pub static ref GDT: (GlobalDescriptorTable, Selectors) = { let mut gdt = GlobalDescriptorTable::new(); - let kernel_data_flags = DescriptorFlags::USER_SEGMENT | DescriptorFlags::PRESENT | DescriptorFlags::WRITABLE; - let code = gdt.add_entry(Descriptor::kernel_code_segment()); - let data = gdt.add_entry(Descriptor::UserSegment(kernel_data_flags.bits())); let tss = gdt.add_entry(Descriptor::tss_segment(&TSS)); + let code = gdt.add_entry(Descriptor::kernel_code_segment()); + let data = gdt.add_entry(Descriptor::kernel_data_segment()); let user_code = gdt.add_entry(Descriptor::user_code_segment()); let user_data = gdt.add_entry(Descriptor::user_data_segment()); - (gdt, Selectors { code, data, tss, user_code, user_data }) + (gdt, Selectors { tss, code, data, user_code, user_data }) }; } pub struct Selectors { + tss: SegmentSelector, code: SegmentSelector, data: SegmentSelector, - tss: SegmentSelector, pub user_code: SegmentSelector, pub user_data: SegmentSelector, } From 0ba77d4305c8bd48c81c1dfaa5958d7487652ea9 Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sat, 25 Sep 2021 23:46:37 +0200 Subject: [PATCH 06/16] Refactor wrap macro --- src/sys/idt.rs | 72 ++++++++++++++++++++++++-------------------------- 1 file changed, 35 insertions(+), 37 deletions(-) diff --git a/src/sys/idt.rs b/src/sys/idt.rs index 6154a399e..643393dca 100644 --- a/src/sys/idt.rs +++ b/src/sys/idt.rs @@ -144,43 +144,41 @@ macro_rules! wrap { #[naked] pub unsafe extern "sysv64" fn $w() { asm!( - " - push rbp - push rax - push rbx - push rcx - push rdx - push rsi - push rdi - push r8 - push r9 - push r10 - push r11 - push r12 - push r13 - push r14 - push r15 - mov rsi, rsp // arg2: register list - mov rdi, rsp - add rdi, 15*8 // arg1: interupt frame - call {} - pop r15 - pop r14 - pop r13 - pop r12 - pop r11 - pop r10 - pop r9 - pop r8 - pop rdi - pop rsi - pop rdx - pop rcx - pop rbx - pop rax - pop rbp - iretq - ", + "push rbp", + "push rax", + "push rbx", + "push rcx", + "push rdx", + "push rsi", + "push rdi", + "push r8", + "push r9", + "push r10", + "push r11", + "push r12", + "push r13", + "push r14", + "push r15", + "mov rsi, rsp", // Arg #2: register list + "mov rdi, rsp", // Arg #1: interupt frame + "add rdi, 15 * 8", + "call {}", + "pop r15", + "pop r14", + "pop r13", + "pop r12", + "pop r11", + "pop r10", + "pop r9", + "pop r8", + "pop rdi", + "pop rsi", + "pop rdx", + "pop rcx", + "pop rbx", + "pop rax", + "pop rbp", + "iretq", sym $fn, options(noreturn) ); From f0f17c95976d59f03b2dc71d96a43ca1d05c2095 Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sat, 25 Sep 2021 23:46:58 +0200 Subject: [PATCH 07/16] Remove debug from process --- src/sys/process.rs | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/sys/process.rs b/src/sys/process.rs index abdc76f61..722db9b6d 100644 --- a/src/sys/process.rs +++ b/src/sys/process.rs @@ -155,7 +155,6 @@ impl Process { let frame = frame_allocator.allocate_frame().unwrap(); for i in 0..1024 { let addr = code_addr + i * PAGE_SIZE; - //printk!("DEBUG: map {:#x} (virt: {:#x})\n", addr, i * PAGE_SIZE); let page = Page::containing_address(VirtAddr::new(addr)); unsafe { mapper.map_to(page, frame, flags, &mut frame_allocator).unwrap().flush(); @@ -164,25 +163,19 @@ impl Process { let mut entry = 0; let code_ptr = code_addr as *mut u8; - if &bin[1..4] == b"ELF" { - // ELF binary + if &bin[1..4] == b"ELF" { // ELF binary if let Ok(obj) = object::File::parse(bin) { entry = obj.entry(); for section in obj.sections() { - use crate::api::syscall::sleep; if let Ok(name) = section.name() { let addr = section.address() as usize; - //let size = section.size(); - //let align = section.align(); if name.is_empty() || addr == 0 { continue; } if let Ok(data) = section.data() { - //printk!("DEBUG: {}\n", name); unsafe { for (i, op) in data.iter().enumerate() { let ptr = code_ptr.add(addr + i); - //printk!("DEBUG: ptr {:#x} (virt: {:#x})\n", ptr as usize, addr + i); core::ptr::write(ptr, *op); } } @@ -190,11 +183,11 @@ impl Process { } } } - } else { - // Raw binary + } else { // Raw binary unsafe { for (i, op) in bin.iter().enumerate() { - core::ptr::write(code_ptr.add(i), *op); + let ptr = code_ptr.add(i); + core::ptr::write(ptr, *op); } } } From dbee446ae52b43da894f0521fa7481f97a3600fe Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sat, 25 Sep 2021 23:48:32 +0200 Subject: [PATCH 08/16] Remove jump to entry point --- src/sys/process.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/sys/process.rs b/src/sys/process.rs index 722db9b6d..7f7a63565 100644 --- a/src/sys/process.rs +++ b/src/sys/process.rs @@ -197,25 +197,24 @@ impl Process { Process { stack_addr, code_addr, entry } } - // Switch to userspace + // Switch to user mode pub fn switch(&self) { + //x86_64::instructions::tlb::flush_all(); let data = GDT.1.user_data.0; let code = GDT.1.user_code.0; unsafe { interrupts::disable(); asm!( - "push rax", - "push rsi", - "push 0x200", - "push rdx", + "push rax", // Data segment + "push rsi", // Stack pointer + "push 0x200", // Interrupt flag + "push rdx", // Code segment "push rdi", - "jmp r8", "iretq", in("rax") data, in("rsi") self.stack_addr, in("rdx") code, - in("rdi") self.code_addr, - in("r8") self.code_addr + self.entry, + in("rdi") self.code_addr + self.entry, ); } } From f2a0fb7c936b80a1423865900f4149f7b5f90a0d Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sat, 25 Sep 2021 23:49:59 +0200 Subject: [PATCH 09/16] Update hello binary --- dsk/bin/hello | Bin 46 -> 1168 bytes 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 dsk/bin/hello diff --git a/dsk/bin/hello b/dsk/bin/hello old mode 100644 new mode 100755 index ef4d97d158e25c5bcb7ed8baa72f5010703ffa6c..534a1ec420eb4d02b52973d29128dd8e0eb5a954 GIT binary patch literal 1168 zcmb<-^>JfjWMqH=CI&kOFb^u^0F@A6hN)m+aA2?is&QaoV_*fVWk*P1u=toDLNJ;^ z07J=u3hZD7TE8FUS&w}TP`B>l19HzcynZ~OE~Ag-9;rDw`8o>W`9(P?id?wu1ceX_ z!^i*VDn!8oz<`5>9ZX&h$PfUf4rn@piA#dTnHb>d0V<)2LtF*HMI{XJsVRvii9jkZg@Hk@xH7jSF$qYQ6hY_= z7^@_;qJ%*YtQP7VvMFhxPLP+`U?#x)52a;c;!qkrJ17FhK}zA-4d!ns4N98GfCZTY zWP|j=v>;2t!fyps5Tp-e2M3fd0i`*i;!rM}+5t7x5H12?K)nSQ6$G;2ZikC9Fua87 MS4R>9G12t{01e(U2><{9 literal 46 ucmdnN%D}*|pAkrS>{9@eAh3%MNStkW{TN7jq~_%0>nMch7v-cVasdF{whH Date: Sun, 26 Sep 2021 08:46:14 +0200 Subject: [PATCH 10/16] Improve comments on asm code --- src/sys/process.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sys/process.rs b/src/sys/process.rs index 7f7a63565..6754abfda 100644 --- a/src/sys/process.rs +++ b/src/sys/process.rs @@ -205,11 +205,11 @@ impl Process { unsafe { interrupts::disable(); asm!( - "push rax", // Data segment - "push rsi", // Stack pointer - "push 0x200", // Interrupt flag - "push rdx", // Code segment - "push rdi", + "push rax", // Stack segment (SS) + "push rsi", // Stack pointer (RSP) + "push 0x200", // RFLAGS with interrupt + "push rdx", // Code segment (CS) + "push rdi", // Instruction pointer (RIP) "iretq", in("rax") data, in("rsi") self.stack_addr, From eddf21e8ba026f391b83437aaffe75f91fc7c1d5 Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sun, 26 Sep 2021 08:53:37 +0200 Subject: [PATCH 11/16] Rename Process#entry to Process#entry_point --- src/sys/process.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sys/process.rs b/src/sys/process.rs index 6754abfda..cb3640b57 100644 --- a/src/sys/process.rs +++ b/src/sys/process.rs @@ -134,7 +134,7 @@ const PAGE_SIZE: u64 = 4 * 1024; pub struct Process { stack_addr: u64, code_addr: u64, - entry: u64, + entry_point: u64, } impl Process { @@ -161,11 +161,11 @@ impl Process { } } - let mut entry = 0; + let mut entry_point = 0; let code_ptr = code_addr as *mut u8; if &bin[1..4] == b"ELF" { // ELF binary if let Ok(obj) = object::File::parse(bin) { - entry = obj.entry(); + entry_point = obj.entry(); for section in obj.sections() { if let Ok(name) = section.name() { let addr = section.address() as usize; @@ -194,7 +194,7 @@ impl Process { set_code_addr(code_addr); - Process { stack_addr, code_addr, entry } + Process { stack_addr, code_addr, entry_point } } // Switch to user mode @@ -214,7 +214,7 @@ impl Process { in("rax") data, in("rsi") self.stack_addr, in("rdx") code, - in("rdi") self.code_addr + self.entry, + in("rdi") self.code_addr + self.entry_point, ); } } From 1bd278164d74c9dd8be60a7978e265f617d49c31 Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sun, 26 Sep 2021 10:14:37 +0200 Subject: [PATCH 12/16] Use cli directly --- src/sys/idt.rs | 3 +-- src/sys/keyboard.rs | 1 - src/sys/process.rs | 5 ++--- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/sys/idt.rs b/src/sys/idt.rs index 643393dca..649395025 100644 --- a/src/sys/idt.rs +++ b/src/sys/idt.rs @@ -17,8 +17,7 @@ fn interrupt_index(irq: u8) -> u8 { sys::pic::PIC_1_OFFSET + irq } -fn default_irq_handler() { -} +fn default_irq_handler() {} lazy_static! { pub static ref IRQ_HANDLERS: Mutex<[fn(); 16]> = Mutex::new([default_irq_handler; 16]); diff --git a/src/sys/keyboard.rs b/src/sys/keyboard.rs index 1fdde65b6..1b66d1978 100644 --- a/src/sys/keyboard.rs +++ b/src/sys/keyboard.rs @@ -53,7 +53,6 @@ pub fn set_keyboard(layout: &str) -> bool { pub fn init() { set_keyboard(option_env!("MOROS_KEYBOARD").unwrap_or("qwerty")); - sys::idt::set_irq_handler(1, interrupt_handler); } diff --git a/src/sys/process.rs b/src/sys/process.rs index cb3640b57..f2aa7452a 100644 --- a/src/sys/process.rs +++ b/src/sys/process.rs @@ -123,7 +123,6 @@ use crate::sys; use crate::sys::gdt::GDT; use core::sync::atomic::AtomicU64; use x86_64::VirtAddr; -use x86_64::instructions::interrupts; use x86_64::structures::paging::{Mapper, FrameAllocator}; use x86_64::structures::paging::{Page, PageTableFlags}; @@ -203,11 +202,11 @@ impl Process { let data = GDT.1.user_data.0; let code = GDT.1.user_code.0; unsafe { - interrupts::disable(); asm!( + "cli", // Disable interrupts "push rax", // Stack segment (SS) "push rsi", // Stack pointer (RSP) - "push 0x200", // RFLAGS with interrupt + "push 0x200", // RFLAGS with interrupts enabled "push rdx", // Code segment (CS) "push rdi", // Instruction pointer (RIP) "iretq", From 4324e68b02aaf0e1666030b2e538d11eca025bfa Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sun, 26 Sep 2021 13:06:06 +0200 Subject: [PATCH 13/16] Add pic::init() --- src/lib.rs | 2 +- src/sys/pic.rs | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 23b6f7245..0caa5da2c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,7 +22,7 @@ pub fn init(boot_info: &'static BootInfo) { sys::vga::init(); sys::gdt::init(); sys::idt::init(); - unsafe { sys::pic::PICS.lock().initialize() }; + sys::pic::init(); x86_64::instructions::interrupts::enable(); log!("MOROS v{}\n", env!("CARGO_PKG_VERSION")); diff --git a/src/sys/pic.rs b/src/sys/pic.rs index bda1d3512..2d49cf999 100644 --- a/src/sys/pic.rs +++ b/src/sys/pic.rs @@ -5,3 +5,9 @@ pub const PIC_1_OFFSET: u8 = 32; pub const PIC_2_OFFSET: u8 = PIC_1_OFFSET + 8; pub static PICS: Mutex = Mutex::new(unsafe { ChainedPics::new(PIC_1_OFFSET, PIC_2_OFFSET) }); + +pub fn init() { + unsafe { + PICS.lock().initialize(); + } +} From f3ac4fbe3a8d906ba39c65ff141e5e13b4bfd1cc Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sun, 26 Sep 2021 13:06:44 +0200 Subject: [PATCH 14/16] Disable again interrupts after halt if needed --- src/sys/time.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/sys/time.rs b/src/sys/time.rs index 726fd305e..be20fbb9d 100644 --- a/src/sys/time.rs +++ b/src/sys/time.rs @@ -30,7 +30,11 @@ pub fn last_rtc_update() -> usize { } pub fn halt() { - x86_64::instructions::interrupts::enable_and_hlt(); + let disabled = !interrupts::are_enabled(); + interrupts::enable_and_hlt(); + if disabled { + interrupts::disable(); + } } fn rdtsc() -> u64 { From 30830e55740213fcf08b37a7b0eec4b53d92dbbe Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sun, 26 Sep 2021 13:55:05 +0200 Subject: [PATCH 15/16] Allow keyboard and serial events during memory init --- src/lib.rs | 10 ++++------ src/sys/mem.rs | 35 +++++++++++++++++++---------------- src/sys/pic.rs | 1 + 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 0caa5da2c..1fc49cdb5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,14 +22,12 @@ pub fn init(boot_info: &'static BootInfo) { sys::vga::init(); sys::gdt::init(); sys::idt::init(); - sys::pic::init(); - x86_64::instructions::interrupts::enable(); + sys::pic::init(); // Enable interrupts + sys::serial::init(); + sys::keyboard::init(); + sys::time::init(); log!("MOROS v{}\n", env!("CARGO_PKG_VERSION")); - - sys::time::init(); - sys::keyboard::init(); - sys::serial::init(); sys::mem::init(boot_info); sys::cpu::init(); sys::pci::init(); // Require MEM diff --git a/src/sys/mem.rs b/src/sys/mem.rs index 080d6de4c..6f990aace 100644 --- a/src/sys/mem.rs +++ b/src/sys/mem.rs @@ -1,5 +1,6 @@ use crate::sys; use bootloader::bootinfo::{BootInfo, MemoryMap, MemoryRegionType}; +use x86_64::instructions::interrupts; use x86_64::structures::paging::{FrameAllocator, OffsetPageTable, PageTable, PhysFrame, Size4KiB, Translate}; use x86_64::{PhysAddr, VirtAddr}; @@ -8,22 +9,24 @@ pub static mut PHYS_MEM_OFFSET: u64 = 0; pub static mut MEMORY_MAP: Option<&MemoryMap> = None; pub fn init(boot_info: &'static BootInfo) { - let mut memory_size = 0; - for region in boot_info.memory_map.iter() { - let start_addr = region.range.start_addr(); - let end_addr = region.range.end_addr(); - memory_size += end_addr - start_addr; - log!("MEM [{:#016X}-{:#016X}] {:?}\n", start_addr, end_addr, region.region_type); - } - log!("MEM {} KB\n", memory_size >> 10); - - unsafe { PHYS_MEM_OFFSET = boot_info.physical_memory_offset; } - unsafe { MEMORY_MAP.replace(&boot_info.memory_map) }; - - let mut mapper = unsafe { mapper(VirtAddr::new(PHYS_MEM_OFFSET)) }; - let mut frame_allocator = unsafe { BootInfoFrameAllocator::init(&boot_info.memory_map) }; - - sys::allocator::init_heap(&mut mapper, &mut frame_allocator).expect("heap initialization failed"); + interrupts::without_interrupts(|| { + let mut memory_size = 0; + for region in boot_info.memory_map.iter() { + let start_addr = region.range.start_addr(); + let end_addr = region.range.end_addr(); + memory_size += end_addr - start_addr; + log!("MEM [{:#016X}-{:#016X}] {:?}\n", start_addr, end_addr, region.region_type); + } + log!("MEM {} KB\n", memory_size >> 10); + + unsafe { PHYS_MEM_OFFSET = boot_info.physical_memory_offset; } + unsafe { MEMORY_MAP.replace(&boot_info.memory_map) }; + + let mut mapper = unsafe { mapper(VirtAddr::new(PHYS_MEM_OFFSET)) }; + let mut frame_allocator = unsafe { BootInfoFrameAllocator::init(&boot_info.memory_map) }; + + sys::allocator::init_heap(&mut mapper, &mut frame_allocator).expect("heap initialization failed"); + }); } pub fn phys_to_virt(addr: PhysAddr) -> VirtAddr { diff --git a/src/sys/pic.rs b/src/sys/pic.rs index 2d49cf999..cce154cd0 100644 --- a/src/sys/pic.rs +++ b/src/sys/pic.rs @@ -10,4 +10,5 @@ pub fn init() { unsafe { PICS.lock().initialize(); } + x86_64::instructions::interrupts::enable(); } From 05d4cef73df9567b4c012c662710eb216b9ed14a Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sun, 26 Sep 2021 22:17:14 +0200 Subject: [PATCH 16/16] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a76b36463..fbe7982fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Changelog ## Unreleased +- Add ELF loader (#248) - Add basic userspace (#228) - Bump acpi from 3.1.0 to 4.0.0 (#243) - Bump sha2 from 0.9.6 to 0.9.8 (#244)