From 0a9c2948149b058f08f127d96b10d098913ab8f3 Mon Sep 17 00:00:00 2001 From: WangRunji Date: Sun, 9 Sep 2018 01:25:14 +0800 Subject: [PATCH] Fix x86_64 startup. TODO: higher half. * Remove legacy boot, MP, ACPI. * Disable SMP. * Modify startup: boot -> arch::init -> kmain. * Fix FrameAllocator on x86_64. * Remove kernel remap. * Alloc kernel heap at bss. --- kernel/Cargo.lock | 10 - kernel/Cargo.toml | 1 - kernel/src/arch/riscv32/memory.rs | 1 - kernel/src/arch/riscv32/mod.rs | 5 +- kernel/src/arch/x86_64/boot/boot.asm | 173 ------------------ kernel/src/arch/x86_64/boot/entryother.asm | 141 -------------- kernel/src/arch/x86_64/boot/grub.cfg | 7 - kernel/src/arch/x86_64/boot/linker.ld | 104 ----------- .../src/arch/x86_64/boot/long_mode_init.asm | 29 --- .../src/arch/x86_64/boot/multiboot_header.asm | 15 -- kernel/src/arch/x86_64/driver/acpi/mod.rs | 61 ------ kernel/src/arch/x86_64/driver/acpi/structs.rs | 141 -------------- kernel/src/arch/x86_64/driver/apic/ioapic.rs | 3 +- kernel/src/arch/x86_64/driver/apic/lapic.rs | 2 +- kernel/src/arch/x86_64/driver/apic/mod.rs | 7 +- kernel/src/arch/x86_64/driver/mod.rs | 12 +- kernel/src/arch/x86_64/driver/mp/mod.rs | 113 ------------ kernel/src/arch/x86_64/driver/mp/structs.rs | 74 -------- kernel/src/arch/x86_64/memory.rs | 110 ++--------- kernel/src/arch/x86_64/mod.rs | 31 +++- kernel/src/lang.rs | 2 +- kernel/src/lib.rs | 15 +- kernel/src/main.rs | 7 - kernel/src/memory.rs | 17 +- kernel/src/util.rs | 21 --- 25 files changed, 60 insertions(+), 1042 deletions(-) delete mode 100644 kernel/src/arch/x86_64/boot/boot.asm delete mode 100644 kernel/src/arch/x86_64/boot/entryother.asm delete mode 100644 kernel/src/arch/x86_64/boot/grub.cfg delete mode 100644 kernel/src/arch/x86_64/boot/linker.ld delete mode 100644 kernel/src/arch/x86_64/boot/long_mode_init.asm delete mode 100644 kernel/src/arch/x86_64/boot/multiboot_header.asm delete mode 100644 kernel/src/arch/x86_64/driver/acpi/mod.rs delete mode 100644 kernel/src/arch/x86_64/driver/acpi/structs.rs delete mode 100644 kernel/src/arch/x86_64/driver/mp/mod.rs delete mode 100644 kernel/src/arch/x86_64/driver/mp/structs.rs diff --git a/kernel/Cargo.lock b/kernel/Cargo.lock index 57d4971..ada7d13 100644 --- a/kernel/Cargo.lock +++ b/kernel/Cargo.lock @@ -110,14 +110,6 @@ dependencies = [ "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "multiboot2" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "once" version = "0.3.3" @@ -227,7 +219,6 @@ dependencies = [ "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "linked_list_allocator 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "multiboot2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "once 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "riscv 0.3.0", @@ -337,7 +328,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d" "checksum linked_list_allocator 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "655d57c71827fe0891ce72231b6aa5e14033dae3f604609e6a6f807267c1678d" "checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f" -"checksum multiboot2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6ebbe89ab663a65cab341428d5fc7013b0eab5543ace92a401a86581e50fdd81" "checksum once 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "931fb7a4cf34610cf6cbe58d52a8ca5ef4c726d4e2e178abd0dc13a6551c6d73" "checksum os_bootinfo 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "66481dbeb5e773e7bd85b63cd6042c30786f834338288c5ec4f3742673db360a" "checksum pulldown-cmark 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8361e81576d2e02643b04950e487ec172b687180da65c731c03cf336784e6c07" diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index 86335ce..55e224f 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -33,7 +33,6 @@ simple-filesystem = { git = "https://github.com/wangrunji0408/SimpleFileSystem-R [target.'cfg(target_arch = "x86_64")'.dependencies] bootloader = "0.3" -multiboot2 = "0.7" x86_64 = "0.2.11" redox_syscall = "0.1" uart_16550 = "0.1" diff --git a/kernel/src/arch/riscv32/memory.rs b/kernel/src/arch/riscv32/memory.rs index 7ec687c..0f9cfb6 100644 --- a/kernel/src/arch/riscv32/memory.rs +++ b/kernel/src/arch/riscv32/memory.rs @@ -46,7 +46,6 @@ fn remap_the_kernel() { ms.push(MemoryArea::new_identity(sdata as usize, edata as usize, MemoryAttr::default(), "data")); ms.push(MemoryArea::new_identity(srodata as usize, erodata as usize, MemoryAttr::default().readonly(), "rodata")); ms.push(MemoryArea::new_identity(sbss as usize, ebss as usize, MemoryAttr::default(), "bss")); - ms.push(MemoryArea::new_identity(KERNEL_HEAP_OFFSET, KERNEL_HEAP_OFFSET + KERNEL_HEAP_SIZE, MemoryAttr::default(), "kernel_heap")); unsafe { ms.activate(); } use core::mem::forget; forget(ms); diff --git a/kernel/src/arch/riscv32/mod.rs b/kernel/src/arch/riscv32/mod.rs index 524201c..13d9ad3 100644 --- a/kernel/src/arch/riscv32/mod.rs +++ b/kernel/src/arch/riscv32/mod.rs @@ -8,11 +8,14 @@ pub mod paging; pub mod memory; pub mod compiler_rt; -pub fn init() { +#[no_mangle] +pub extern fn rust_main() -> ! { println!("Hello RISCV! {}", 123); + ::logging::init(); interrupt::init(); memory::init(); timer::init(); + ::kmain(); } #[cfg(feature = "no_bbl")] diff --git a/kernel/src/arch/x86_64/boot/boot.asm b/kernel/src/arch/x86_64/boot/boot.asm deleted file mode 100644 index c72f4bf..0000000 --- a/kernel/src/arch/x86_64/boot/boot.asm +++ /dev/null @@ -1,173 +0,0 @@ -global start -global stack_bottom -global stack_top -extern long_mode_start - -section .text -bits 32 -start: - mov esp, stack_top - push ebx ; push Multiboot info pointer to stack_top - - call check_multiboot - call check_cpuid - call check_long_mode - - call set_up_page_tables - call enable_paging - - ; load the 64-bit GDT - lgdt [gdt64.pointer] - - jmp gdt64.code:long_mode_start - - ; print `OK` to screen - mov dword [0xb8000], 0x2f4b2f4f - hlt - -check_multiboot: - cmp eax, 0x36d76289 - jne .no_multiboot - ret -.no_multiboot: - mov al, "0" - jmp error - -check_cpuid: - ; Check if CPUID is supported by attempting to flip the ID bit (bit 21) - ; in the FLAGS register. If we can flip it, CPUID is available. - - ; Copy FLAGS in to EAX via stack - pushfd - pop eax - - ; Copy to ECX as well for comparing later on - mov ecx, eax - - ; Flip the ID bit - xor eax, 1 << 21 - - ; Copy EAX to FLAGS via the stack - push eax - popfd - - ; Copy FLAGS back to EAX (with the flipped bit if CPUID is supported) - pushfd - pop eax - - ; Restore FLAGS from the old version stored in ECX (i.e. flipping the - ; ID bit back if it was ever flipped). - push ecx - popfd - - ; Compare EAX and ECX. If they are equal then that means the bit - ; wasn't flipped, and CPUID isn't supported. - cmp eax, ecx - je .no_cpuid - ret -.no_cpuid: - mov al, "1" - jmp error - -check_long_mode: - ; test if extended processor info in available - mov eax, 0x80000000 ; implicit argument for cpuid - cpuid ; get highest supported argument - cmp eax, 0x80000001 ; it needs to be at least 0x80000001 - jb .no_long_mode ; if it's less, the CPU is too old for long mode - - ; use extended info to test if long mode is available - mov eax, 0x80000001 ; argument for extended processor info - cpuid ; returns various feature bits in ecx and edx - test edx, 1 << 29 ; test if the LM-bit is set in the D-register - jz .no_long_mode ; If it's not set, there is no long mode - ret -.no_long_mode: - mov al, "2" - jmp error - -set_up_page_tables: - ; map P4 table recursively - mov eax, p4_table - or eax, 0b11 ; present + writable - mov [p4_table + 511 * 8], eax - - ; map first & 510th P4 entry to P3 table - mov eax, p3_table - or eax, 0b11 ; present + writable - mov [p4_table], eax - mov [p4_table + 510 * 8], eax - - ; map first P3 entry to P2 table - mov eax, p2_table - or eax, 0b11 ; present + writable - mov [p3_table], eax - - ; map each P2 entry to a huge 2MiB page - mov ecx, 0 ; counter variable - -.map_p2_table: - ; map ecx-th P2 entry to a huge page that starts at address 2MiB*ecx - mov eax, 0x200000 ; 2MiB - mul ecx ; start address of ecx-th page - or eax, 0b10000011 ; present + writable + huge - mov [p2_table + ecx * 8], eax ; map ecx-th entry - - inc ecx ; increase counter - cmp ecx, 512 ; if counter == 512, the whole P2 table is mapped - jne .map_p2_table ; else map the next entry - - ret - -enable_paging: - ; load P4 to cr3 register (cpu uses this to access the P4 table) - mov eax, p4_table - mov cr3, eax - - ; enable PAE-flag in cr4 (Physical Address Extension) - mov eax, cr4 - or eax, 1 << 5 - mov cr4, eax - - ; set the long mode bit & no execute bit in the EFER MSR (model specific register) - mov ecx, 0xC0000080 - rdmsr - or eax, 1 << 8 | 1 << 11 - wrmsr - - ; enable paging & write protect in the cr0 register - mov eax, cr0 - or eax, 1 << 31 | 1 << 16 - mov cr0, eax - - ret - -; Prints `ERR: ` and the given error code to screen and hangs. -; parameter: error code (in ascii) in al -error: - mov dword [0xb8000], 0x4f524f45 - mov dword [0xb8004], 0x4f3a4f52 - mov dword [0xb8008], 0x4f204f20 - mov byte [0xb800a], al - hlt - -section .bss -align 4096 -p4_table: - resb 4096 -p3_table: - resb 4096 -p2_table: - resb 4096 -stack_bottom: - resb 4096 * 8 -stack_top: - -section .rodata -gdt64: - dq 0 ; zero entry -.code: equ $ - gdt64 ; new - dq (1<<43) | (1<<44) | (1<<47) | (1<<53) ; code segment -.pointer: - dw $ - gdt64 - 1 - dq gdt64 diff --git a/kernel/src/arch/x86_64/boot/entryother.asm b/kernel/src/arch/x86_64/boot/entryother.asm deleted file mode 100644 index b8fc568..0000000 --- a/kernel/src/arch/x86_64/boot/entryother.asm +++ /dev/null @@ -1,141 +0,0 @@ -; xv6 x86_64 entryother.S - -; Each non-boot CPU ("AP") is started up in response to a STARTUP -; IPI from the boot CPU. Section B.4.2 of the Multi-Processor -; Specification says that the AP will start in real mode with CS:IP -; set to XY00:0000, where XY is an 8-bit value sent with the -; STARTUP. Thus this code must start at a 4096-byte boundary. -; -; Because this code sets DS to zero, it must sit -; at an address in the low 2^16 bytes. -; -; Startothers (in main.c) sends the STARTUPs one at a time. -; It copies this code (start) at 0x7000. It puts the address of -; a newly allocated per-core stack in start-4,the address of the -; place to jump to (mpenter) in start-8, and the physical address -; of entrypgdir in start-12. -; -; This code is identical to bootasm.S except: -; - it does not need to enable A20 -; - it uses the address at start-4, start-8, and start-12 - -%define CR0_PE 1 -%define STA_X 0x8 ; Executable segment -%define STA_E 0x4 ; Expand down (non-executable segments) -%define STA_C 0x4 ; Conforming code segment (executable only) -%define STA_W 0x2 ; Writeable (non-executable segments) -%define STA_R 0x2 ; Readable (executable segments) -%define STA_A 0x1 ; Accessed - -extern other_main - -section .text -bits 16 -start: - cli - - xor ax, ax - mov ds, ax - mov es, ax - mov ss, ax - - lgdt [gdt.desc] - mov eax, cr0 - or eax, CR0_PE - mov cr0, eax - - jmp gdt.code: start32 - -bits 32 -start32: - mov ax, gdt.data - mov ds, ax - mov es, ax - mov ss, ax - mov ax, 0 - mov fs, ax - mov gs, ax - - ; Switch to the stack allocated by startothers() - mov esp, [top - 4] - - call enable_paging - - ; load the 64-bit GDT - lgdt [gdt64.pointer] - - jmp gdt64.code: start64 - -error: - mov ax, 0x8a00 - mov dx, ax - out dx, ax - mov ax, 0x8ae0 - out dx, ax -spin: - jmp spin - -enable_paging: - ; load P4 to cr3 register (cpu uses this to access the P4 table) - mov eax, [top - 8] - mov cr3, eax - - ; enable PAE-flag in cr4 (Physical Address Extension) - mov eax, cr4 - or eax, 1 << 5 - mov cr4, eax - - ; set the long mode bit & no execute bit in the EFER MSR (model specific register) - mov ecx, 0xC0000080 - rdmsr - or eax, 1 << 8 | 1 << 11 - wrmsr - - ; enable paging & write protect in the cr0 register - mov eax, cr0 - or eax, 1 << 31 | 1 << 16 - mov cr0, eax - - ret - -bits 64 -start64: - ; load 0 into all data segment registers - mov ax, 0 - mov ss, ax - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - - ; obtain kstack from data block before entryother - mov rsp, [top - 16] - - mov rax, other_main - call rax - -; section .rodata -align 4 -gdt: - ; NULL - dw 0, 0 - db 0, 0, 0, 0 -.code: equ $ - gdt - dw 0xffff, 0 - db 0, (0x90 | STA_X | STA_R), 0xcf, 0 -.data: equ $ - gdt - dw 0xffff, 0 - db 0, (0x90 | STA_W), 0xcf, 0 -.desc: - dw $ - gdt - 1 - dq gdt - -gdt64: - dq 0 ; zero entry -.code: equ $ - gdt64 ; new - dq (1<<43) | (1<<44) | (1<<47) | (1<<53) ; code segment -.pointer: - dw $ - gdt64 - 1 - dq gdt64 - -top: equ start + 0x1000 \ No newline at end of file diff --git a/kernel/src/arch/x86_64/boot/grub.cfg b/kernel/src/arch/x86_64/boot/grub.cfg deleted file mode 100644 index a841c00..0000000 --- a/kernel/src/arch/x86_64/boot/grub.cfg +++ /dev/null @@ -1,7 +0,0 @@ -set timeout=0 -set default=0 - -menuentry "my os" { - multiboot2 /boot/kernel.bin - boot -} diff --git a/kernel/src/arch/x86_64/boot/linker.ld b/kernel/src/arch/x86_64/boot/linker.ld deleted file mode 100644 index 67be813..0000000 --- a/kernel/src/arch/x86_64/boot/linker.ld +++ /dev/null @@ -1,104 +0,0 @@ -ENTRY(start) - -OTHER_OFFSET = 0x7000; -BOOT_OFFSET = 0x100000; -KERNEL_OFFSET = 0xffffff0000000000; - -SECTIONS { - - /* ensure that the multiboot header is at the beginning */ - - .multiboot_header : - { - KEEP(*(.multiboot_header)) - } - - /* bootloader for other processors */ - - . = OTHER_OFFSET; - - .text.other : AT(OTHER_OFFSET) - { - KEEP(*/entryother.o (.text)) - . = ALIGN(4K); - } - - /* bootloader for first processor */ - - . = BOOT_OFFSET; - - .rodata.32 : - { - */boot.o (.rodata) - . = ALIGN(4K); - } - .text.32 : - { - */boot.o (.text) - */long_mode_init.o (.text) - . = ALIGN(4K); - } - .bss.32 : - { - */boot.o (.bss) - . = ALIGN(4K); - } - - /* kernel */ - - . += KERNEL_OFFSET; - - .user ALIGN(4K): AT(ADDR(.user) - KERNEL_OFFSET) - { - KEEP(user/*.o (.data)) - . = ALIGN(4K); - } - - .rodata : AT(ADDR(.rodata) - KERNEL_OFFSET) - { - *(.rodata .rodata.*) - . = ALIGN(4K); - } - - .text : AT(ADDR(.text) - KERNEL_OFFSET) - { - *(.text .text.*) - . = ALIGN(4K); - } - - .data : AT(ADDR(.data) - KERNEL_OFFSET) - { - *(.data .data.*) - . = ALIGN(4K); - } - - .bss ALIGN(4K): AT(ADDR(.bss) - KERNEL_OFFSET) - { - *(.bss .bss.*) - . = ALIGN(4K); - } - - .got ALIGN(4K): AT(ADDR(.got) - KERNEL_OFFSET) - { - *(.got) - . = ALIGN(4K); - } - - .got.plt : AT(ADDR(.got.plt) - KERNEL_OFFSET) - { - *(.got.plt) - . = ALIGN(4K); - } - - .data.rel.ro : AT(ADDR(.data.rel.ro) - KERNEL_OFFSET) - { - *(.data.rel.ro.local*) *(.data.rel.ro .data.rel.ro.*) - . = ALIGN(4K); - } - - .gcc_except_table : AT(ADDR(.gcc_except_table) - KERNEL_OFFSET) - { - *(.gcc_except_table) - . = ALIGN(4K); - } -} diff --git a/kernel/src/arch/x86_64/boot/long_mode_init.asm b/kernel/src/arch/x86_64/boot/long_mode_init.asm deleted file mode 100644 index f277f46..0000000 --- a/kernel/src/arch/x86_64/boot/long_mode_init.asm +++ /dev/null @@ -1,29 +0,0 @@ -global long_mode_start -extern rust_main - -KERNEL_OFFSET equ 0xffff_ff00_0000_0000 - -section .text -bits 64 -long_mode_start: - ; load 0 into all data segment registers - mov ax, 0 - mov ss, ax - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - - ; translate rsp to virtual address - mov rax, KERNEL_OFFSET - add rsp, rax - - ; call the rust main - extern rust_main - mov rax, rust_main - call rax - - ; print `OKAY` to screen - mov rax, 0x2f592f412f4b2f4f - mov qword [0xb8000], rax - hlt diff --git a/kernel/src/arch/x86_64/boot/multiboot_header.asm b/kernel/src/arch/x86_64/boot/multiboot_header.asm deleted file mode 100644 index 9a9289c..0000000 --- a/kernel/src/arch/x86_64/boot/multiboot_header.asm +++ /dev/null @@ -1,15 +0,0 @@ -section .multiboot_header -header_start: - dd 0xe85250d6 ; magic number (multiboot 2) - dd 0 ; architecture 0 (protected mode i386) - dd header_end - header_start ; header length - ; checksum - dd 0x100000000 - (0xe85250d6 + 0 + (header_end - header_start)) - - ; insert optional multiboot tags here - - ; required end tag - dw 0 ; type - dw 0 ; flags - dd 8 ; size -header_end: diff --git a/kernel/src/arch/x86_64/driver/acpi/mod.rs b/kernel/src/arch/x86_64/driver/acpi/mod.rs deleted file mode 100644 index c7acf30..0000000 --- a/kernel/src/arch/x86_64/driver/acpi/mod.rs +++ /dev/null @@ -1,61 +0,0 @@ -// Migrate from xv6-x86_64 acpi.c - -mod structs; -use self::structs::*; -use consts::*; - -pub fn init(rsdt_addr: usize) -> Result { - let rsdt = unsafe { &*(rsdt_addr as *const Rsdt) }; - let mut madt: Option<&'static Madt> = None; - for i in 0 .. rsdt.entry_count() { - let entry = rsdt.entry_at(i); - let header = unsafe{ &*(entry as *const Header) }; - trace!("{:?}", header); - if &header.signature == b"APIC" { - madt = Some(unsafe{ &*(entry as *const Madt) }); - } - } - trace!("{:?}", madt); - config_smp(madt.expect("acpi: madt not found.")) -} - -#[derive(Debug)] -pub struct AcpiResult { - pub cpu_num: u8, - pub cpu_acpi_ids: [u8; MAX_CPU_NUM], - pub ioapic_id: u8, - pub lapic_addr: *const (), -} - -#[derive(Debug)] -pub enum AcpiError { - NotMapped, - IoacpiNotFound, -} - -fn config_smp(madt: &'static Madt) -> Result { - let lapic_addr = madt.lapic_address as *const (); - - let mut cpu_num = 0u8; - let mut cpu_acpi_ids: [u8; MAX_CPU_NUM] = [0; MAX_CPU_NUM]; - let mut ioapic_id: Option = None; - for entry in madt.entry_iter() { - trace!("{:?}", entry); - match &entry { - &MadtEntry::LocalApic(ref lapic) => { - cpu_acpi_ids[cpu_num as usize] = lapic.id; - cpu_num += 1; - }, - &MadtEntry::IoApic(ref ioapic) => { - ioapic_id = Some(ioapic.id); - }, - _ => {}, - } - } - - if ioapic_id.is_none() { - return Err(AcpiError::IoacpiNotFound); - } - let ioapic_id = ioapic_id.unwrap(); - Ok(AcpiResult { cpu_num, cpu_acpi_ids, ioapic_id, lapic_addr }) -} diff --git a/kernel/src/arch/x86_64/driver/acpi/structs.rs b/kernel/src/arch/x86_64/driver/acpi/structs.rs deleted file mode 100644 index de38829..0000000 --- a/kernel/src/arch/x86_64/driver/acpi/structs.rs +++ /dev/null @@ -1,141 +0,0 @@ -// Reference: xv6-x86_64 acpi.h -// Copy from crate 'acpica-sys' - -use util::{Checkable, bytes_sum}; -use core::mem::size_of; - -#[repr(C)] -#[derive(Debug)] -pub struct Rsdp { - pub signature: [u8; 8], - pub checksum: u8, - pub oem_id: [i8; 6], - pub revision: u8, - pub rsdt_physical_address: u32, - pub length: u32, - pub xsdt_physical_address: u64, - pub extended_checksum: u8, - pub reserved: [u8; 3], -} - -impl Checkable for Rsdp { - fn check(&self) -> bool { - &self.signature == b"RSD PTR " && bytes_sum(self) == 0 - } -} - -#[repr(C)] -#[derive(Debug)] -pub struct Header { - pub signature: [u8; 4], - pub length: u32, - pub revision: u8, - pub checksum: u8, - pub oem_id: [i8; 6], - pub oem_table_id: [i8; 8], - pub oem_revision: u32, - pub asl_compiler_id: [i8; 4], - pub asl_compiler_revision: u32, -} - -#[repr(C)] -#[derive(Debug)] -pub struct Rsdt { - pub header: Header, - table_offset_entry: [u32; 0], -} - -impl Rsdt { - pub fn entry_count(&self) -> usize { - (self.header.length as usize - size_of::()) / 4 - } - pub fn entry_at(&self, id: usize) -> u32 { - assert!(id < self.entry_count()); - unsafe { - let p = (self as *const Self).offset(1) as *const u32; - *(p.offset(id as isize)) - } - } -} - -#[repr(C)] -#[derive(Debug)] -pub struct Madt { - pub header: Header, - pub lapic_address: u32, - pub flags: u32, - table: [u32; 0], -} - -impl Checkable for Madt { - fn check(&self) -> bool { - &self.header.signature == b"APIC" && self.header.length >= size_of::() as u32 - } -} - -#[derive(Debug)] -pub enum MadtEntry { - Unknown(MadtEntryUnknown), - LocalApic(MadtEntryLocalApic), - IoApic(MadtEntryIoApic), -} -#[repr(C)] -#[derive(Debug, Clone)] -pub struct MadtEntryUnknown { - pub type_: u8, - pub length: u8, -} -#[repr(C)] -#[derive(Debug, Clone)] -pub struct MadtEntryLocalApic { - pub type_: u8, // 0 - pub length: u8, - pub processor_id: u8, - pub id: u8, - pub lapic_flags: u32, -} -#[repr(C)] -#[derive(Debug, Clone)] -pub struct MadtEntryIoApic { - pub type_: u8, // 1 - pub length: u8, - pub id: u8, - pub reserved: u8, - pub address: u32, - pub global_irq_base: u32, -} - -#[derive(Debug)] -pub struct MadtEntryIter<'a> { - madt: &'a Madt, - ptr: *const u8, - end_ptr: *const u8, -} - -impl Madt { - pub fn entry_iter(&self) -> MadtEntryIter { - let ptr = unsafe{ (self as *const Self).offset(1) } as *const u8; - let end_ptr = unsafe{ ptr.offset(self.header.length as isize) }; - MadtEntryIter { madt: self, ptr, end_ptr } - } -} - -impl<'a> Iterator for MadtEntryIter<'a> { - type Item = MadtEntry; - fn next(&mut self) -> Option { - if self.ptr >= self.end_ptr { - return None; - } - unsafe { - let type_id = *self.ptr.offset(0); - let len = *self.ptr.offset(1); - let ret = Some(match type_id { - 0 => MadtEntry::LocalApic( (&*(self.ptr as *const MadtEntryLocalApic)).clone() ), - 1 => MadtEntry::IoApic( (&*(self.ptr as *const MadtEntryIoApic)).clone() ), - _ => MadtEntry::Unknown( (&*(self.ptr as *const MadtEntryUnknown)).clone() ), - }); - self.ptr = self.ptr.offset(len as isize); - ret - } - } -} \ No newline at end of file diff --git a/kernel/src/arch/x86_64/driver/apic/ioapic.rs b/kernel/src/arch/x86_64/driver/apic/ioapic.rs index 755e99d..48e7d35 100644 --- a/kernel/src/arch/x86_64/driver/apic/ioapic.rs +++ b/kernel/src/arch/x86_64/driver/apic/ioapic.rs @@ -9,10 +9,9 @@ use bit_field::BitField; use arch::interrupt::consts::T_IRQ0; use spin::Mutex; -pub fn init(ioapic_id: u8) +pub fn init() { let mut ioapic = IOAPIC.lock(); - assert_eq!(ioapic.id(), ioapic_id, "ioapic.init: id isn't equal to ioapicid; not a MP"); // Mark all interrupts edge-triggered, active high, disabled, // and not routed to any CPUs. diff --git a/kernel/src/arch/x86_64/driver/apic/lapic.rs b/kernel/src/arch/x86_64/driver/apic/lapic.rs index 0201d44..b70e776 100644 --- a/kernel/src/arch/x86_64/driver/apic/lapic.rs +++ b/kernel/src/arch/x86_64/driver/apic/lapic.rs @@ -6,7 +6,7 @@ extern { fn lapicstartap(apicid: u8, addr: u32); } -pub fn set_addr(lapic_addr: *const ()) { +pub fn set_addr(lapic_addr: usize) { unsafe { // lapic = lapic_addr; } diff --git a/kernel/src/arch/x86_64/driver/apic/mod.rs b/kernel/src/arch/x86_64/driver/apic/mod.rs index 2ab9c5f..3cf6af8 100644 --- a/kernel/src/arch/x86_64/driver/apic/mod.rs +++ b/kernel/src/arch/x86_64/driver/apic/mod.rs @@ -4,11 +4,12 @@ pub use self::lapic::{ack, start_ap, lapic_id}; mod lapic; mod ioapic; -pub fn init(lapic_addr: *const (), ioapic_id: u8) { +pub fn init() { assert_has_not_been_called!("apic::init must be called only once"); - self::lapic::set_addr(lapic_addr); + use consts::KERNEL_OFFSET; + self::lapic::set_addr(KERNEL_OFFSET + 0xfee00000); self::lapic::init(); - self::ioapic::init(ioapic_id); + self::ioapic::init(); } pub fn other_init() { diff --git a/kernel/src/arch/x86_64/driver/mod.rs b/kernel/src/arch/x86_64/driver/mod.rs index 4be8d11..5064353 100644 --- a/kernel/src/arch/x86_64/driver/mod.rs +++ b/kernel/src/arch/x86_64/driver/mod.rs @@ -1,31 +1,23 @@ extern crate syscall as redox_syscall; pub mod vga; -pub mod acpi; pub mod apic; -pub mod mp; pub mod serial; pub mod pic; pub mod keyboard; pub mod pit; pub mod ide; -pub fn init(rsdt_addr: usize) -> acpi::AcpiResult { +pub fn init() { assert_has_not_been_called!(); - let acpi = acpi::init(rsdt_addr).expect("Failed to init ACPI"); - assert_eq!(acpi.lapic_addr as usize, 0xfee00000); - trace!("acpi = {:?}", acpi); - if cfg!(feature = "use_apic") { pic::disable(); - use consts::KERNEL_OFFSET; - apic::init((KERNEL_OFFSET + 0xfee00000) as *const (), acpi.ioapic_id); + apic::init(); } else { pic::init(); } pit::init(); serial::init(); keyboard::init(); - acpi } \ No newline at end of file diff --git a/kernel/src/arch/x86_64/driver/mp/mod.rs b/kernel/src/arch/x86_64/driver/mp/mod.rs deleted file mode 100644 index a6a587a..0000000 --- a/kernel/src/arch/x86_64/driver/mp/mod.rs +++ /dev/null @@ -1,113 +0,0 @@ -// Migrate from xv6 mp.c - -// Multiprocessor support -// Search memory for MP description structures. -// http://developer.intel.com/design/pentium/datashts/24201606.pdf - -mod structs; -use self::structs::*; - -/// Search for the MP Floating Pointer Structure, which according to the -/// spec is in one of the following three locations: -/// 1) in the first KB of the EBDA; -/// 2) in the last KB of system base memory; -/// 3) in the BIOS ROM address space between 0F0000h and 0FFFFFh. -pub fn find_mp() -> Option<*const MP> -{ - use core::mem::size_of; - use util::find_in_memory; - let ebda = unsafe { *(0x40E as *const u16) as usize } << 4; - if ebda != 0 { - let res = unsafe{ find_in_memory::(ebda, 1024, size_of::()) }; - if let Some(addr) = res { - return Some(addr as *const MP); - } - } - let p = unsafe { *(0x413 as *const u16) as usize } << 10; - let res = unsafe{ find_in_memory::(p-1024, 1024, size_of::()) }; - if let Some(addr) = res { - return Some(addr as *const MP); - } - let res = unsafe{ find_in_memory::(0xF0000, 0x10000, size_of::()) }; - res.map(|addr| addr as *const MP) -} - -/* -struct cpu cpus[NCPU]; -int ncpu; -uchar ioapicid; - -// Search for an MP configuration table. For now, -// don't accept the default configurations (physaddr == 0). -// Check for correct signature, calculate the checksum and, -// if correct, check the version. -// To do: check extended table checksum. -static struct mpconf* -mpconfig(struct mp **pmp) -{ - struct mpconf *conf; - struct mp *mp; - - if((mp = mpsearch()) == 0 || mp->physaddr == 0) - return 0; - conf = (struct mpconf*) P2V((uint) mp->physaddr); - if(memcmp(conf, "PCMP", 4) != 0) - return 0; - if(conf->version != 1 && conf->version != 4) - return 0; - if(sum((uchar*)conf, conf->length) != 0) - return 0; - *pmp = mp; - return conf; -} - -void -mpinit(void) -{ - uchar *p, *e; - int ismp; - struct mp *mp; - struct mpconf *conf; - struct mpproc *proc; - struct mpioapic *ioapic; - - if((conf = mpconfig(&mp)) == 0) - panic("Expect to run on an SMP"); - ismp = 1; - lapic = (uint*)conf->lapicaddr; - for(p=(uchar*)(conf+1), e=(uchar*)conf+conf->length; papicid; // apicid may differ from ncpu - ncpu++; - } - p += sizeof(struct mpproc); - continue; - case MPIOAPIC: - ioapic = (struct mpioapic*)p; - ioapicid = ioapic->apicno; - p += sizeof(struct mpioapic); - continue; - case MPBUS: - case MPIOINTR: - case MPLINTR: - p += 8; - continue; - default: - ismp = 0; - break; - } - } - if(!ismp) - panic("Didn't find a suitable machine"); - - if(mp->imcrp){ - // Bochs doesn't support IMCR, so this doesn't run on Bochs. - // But it would on real hardware. - outb(0x22, 0x70); // Select IMCR - outb(0x23, inb(0x23) | 1); // Mask external interrupts. - } -} -*/ \ No newline at end of file diff --git a/kernel/src/arch/x86_64/driver/mp/structs.rs b/kernel/src/arch/x86_64/driver/mp/structs.rs deleted file mode 100644 index a3acd68..0000000 --- a/kernel/src/arch/x86_64/driver/mp/structs.rs +++ /dev/null @@ -1,74 +0,0 @@ -// Migrate from xv6 mp.h - -// See MultiProcessor Specification Version 1.[14] - -use util::{Checkable, bytes_sum}; - -#[repr(C)] -#[derive(Debug)] -pub struct MP { // floating pointer - signature: [u8; 4], // "_MP_" - physaddr: u32, // phys addr of MP config table - length: u8, // 1 - specrev: u8, // [14] - checksum: u8, // all bytes must add up to 0 - type_: u8, // MP system config type - imcrp: u8, - reserved: [u8; 3], -} - -impl Checkable for MP { - fn check(&self) -> bool { - &self.signature == b"_MP_" && bytes_sum(self) == 0 - } -} - -/* - -#[repr(C)] -struct mpconf { // configuration table header - signature: [byte; 4]; // "PCMP" - length: u16, // total table length - version: u8, // [14] - checksum: u8, // all bytes must add up to 0 - product: [u8; 20], // product id - uint *oemtable, // OEM table pointer - ushort oemlength, // OEM table length - ushort entry, // entry count - uint *lapicaddr, // address of local APIC - ushort xlength, // extended table length - u8 xchecksum, // extended table checksum - u8 reserved, -} - -#[repr(C)] -struct mpproc { // processor table entry - u8 type; // entry type (0) - u8 apicid; // local APIC id - u8 version; // local APIC verison - u8 flags; // CPU flags - #define MPBOOT 0x02 // This proc is the bootstrap processor. - u8 signature[4]; // CPU signature - uint feature; // feature flags from CPUID instruction - u8 reserved[8]; -} - -struct mpioapic { // I/O APIC table entry - u8 type; // entry type (2) - u8 apicno; // I/O APIC id - u8 version; // I/O APIC version - u8 flags; // I/O APIC flags - uint *addr; // I/O APIC address -} - -// Table entry types -const MPPROC : u8 = 0x00; // One per processor -const MPBUS : u8 = 0x01; // One per bus -const MPIOAPIC : u8 = 0x02; // One per I/O APIC -const MPIOINTR : u8 = 0x03; // One per bus interrupt source -const MPLINTR : u8 = 0x04; // One per system interrupt source - -//PAGEBREAK! -// Blank page. - -*/ diff --git a/kernel/src/arch/x86_64/memory.rs b/kernel/src/arch/x86_64/memory.rs index 1994487..54bd283 100644 --- a/kernel/src/arch/x86_64/memory.rs +++ b/kernel/src/arch/x86_64/memory.rs @@ -1,112 +1,24 @@ -use bit_allocator::{BitAlloc, BitAlloc64K}; +use bit_allocator::BitAlloc; use consts::KERNEL_OFFSET; // Depends on kernel -use memory::{active_table, FRAME_ALLOCATOR, init_heap, MemoryArea, MemoryAttr, MemorySet, Stack}; -use super::multiboot2::{ElfSection, ElfSectionFlags, ElfSectionsTag}; -use super::multiboot2::BootInformation; +use memory::{FRAME_ALLOCATOR, init_heap}; +use super::{BootInfo, MemoryRegionType}; use ucore_memory::PAGE_SIZE; use ucore_memory::paging::PageTable; -// BootInformation may trigger page fault after kernel remap -// So just take its ownership -pub fn init(boot_info: BootInformation) { +pub fn init(boot_info: &BootInfo) { assert_has_not_been_called!("memory::init must be called only once"); - info!("{:?}", boot_info); - init_frame_allocator(&boot_info); -// remap_the_kernel(&boot_info); + init_frame_allocator(boot_info); init_heap(); + info!("memory: init end"); } -fn init_frame_allocator(boot_info: &BootInformation) { - let memory_areas = boot_info.memory_map_tag().expect("Memory map tag required") - .memory_areas(); - let elf_sections = boot_info.elf_sections_tag().expect("Elf sections tag required") - .sections().filter(|s| s.is_allocated()); - +/// Init FrameAllocator and insert all 'Usable' regions from BootInfo. +fn init_frame_allocator(boot_info: &BootInfo) { let mut ba = FRAME_ALLOCATOR.lock(); - for area in memory_areas { - ba.insert(to_range(area.start_address() as usize, area.end_address() as usize)); - } - for section in elf_sections { - ba.remove(to_range(section.start_address() as usize, section.end_address() as usize)); - } - ba.remove(to_range(boot_info.start_address(), boot_info.end_address())); - - use core::ops::Range; - fn to_range(mut start_addr: usize, mut end_addr: usize) -> Range { - use consts::KERNEL_OFFSET; - if start_addr >= KERNEL_OFFSET { - start_addr -= KERNEL_OFFSET; - } - if end_addr >= KERNEL_OFFSET { - end_addr -= KERNEL_OFFSET; + for region in boot_info.memory_map.iter() { + if region.region_type == MemoryRegionType::Usable { + ba.insert(region.range.start_frame_number as usize..region.range.end_frame_number as usize); } - let page_start = start_addr / PAGE_SIZE; - let mut page_end = (end_addr - 1) / PAGE_SIZE + 1; - if page_end >= BitAlloc64K::CAP { - warn!("page num {:#x} out of range {:#x}", page_end, BitAlloc64K::CAP); - page_end = BitAlloc64K::CAP; - } - page_start..page_end - } -} - -fn remap_the_kernel(boot_info: &BootInformation) { - extern { fn stack_bottom(); } - extern { fn stack_top(); } - let kstack = Stack { - top: stack_top as usize + KERNEL_OFFSET, - bottom: stack_bottom as usize + PAGE_SIZE + KERNEL_OFFSET, - }; - - let mut memory_set = memory_set_from(boot_info.elf_sections_tag().unwrap(), kstack); - - use consts::{KERNEL_HEAP_OFFSET, KERNEL_HEAP_SIZE}; - use super::smp::ENTRYOTHER_ADDR; - memory_set.push(MemoryArea::new_physical(0xb8000, 0xb9000, KERNEL_OFFSET, MemoryAttr::default(), "VGA")); - memory_set.push(MemoryArea::new_physical(0xfee00000, 0xfee01000, KERNEL_OFFSET, MemoryAttr::default(), "LAPIC")); - memory_set.push(MemoryArea::new_identity(0x07fe1000, 0x07fe1000 + PAGE_SIZE, MemoryAttr::default(), "RSDT")); - memory_set.push(MemoryArea::new_identity(0xfec00000, 0xfec00000 + PAGE_SIZE, MemoryAttr::default(), "IOAPIC")); - memory_set.push(MemoryArea::new(KERNEL_HEAP_OFFSET, KERNEL_HEAP_OFFSET + KERNEL_HEAP_SIZE, MemoryAttr::default(), "kernel_heap")); - memory_set.push(MemoryArea::new_identity(ENTRYOTHER_ADDR, ENTRYOTHER_ADDR + PAGE_SIZE, MemoryAttr::default().execute(), "entry_other.text")); - memory_set.push(MemoryArea::new_physical(0, 4096, KERNEL_OFFSET, MemoryAttr::default(), "entry_other.ctrl")); - debug!("{:#x?}", memory_set); - - unsafe { memory_set.activate(); } - info!("NEW TABLE!!!"); - - use core::mem::forget; - forget(memory_set); -} - -fn memory_set_from(sections: ElfSectionsTag, kstack: Stack) -> MemorySet { - assert_has_not_been_called!(); - // WARNING: must ensure it's large enough - static mut SPACE: [u8; 0x1000] = [0; 0x1000]; - let mut set = unsafe { MemorySet::new_from_raw_space(&mut SPACE, kstack) }; - for section in sections.sections().filter(|s| s.is_allocated()) { - set.push(memory_area_from(section)); } - set } - -fn memory_area_from(section: ElfSection) -> MemoryArea { - let mut start_addr = section.start_address() as usize; - let mut end_addr = section.end_address() as usize; - assert_eq!(start_addr % PAGE_SIZE, 0, "sections need to be page aligned"); - let name = unsafe { &*(section.name() as *const str) }; - if start_addr >= KERNEL_OFFSET { - start_addr -= KERNEL_OFFSET; - end_addr -= KERNEL_OFFSET; - } - MemoryArea::new_physical(start_addr, end_addr, KERNEL_OFFSET, memory_attr_from(section.flags()), name) -} - -fn memory_attr_from(elf_flags: ElfSectionFlags) -> MemoryAttr { - let mut flags = MemoryAttr::default(); - - if !elf_flags.contains(ElfSectionFlags::ALLOCATED) { flags = flags.hide(); } - if !elf_flags.contains(ElfSectionFlags::WRITABLE) { flags = flags.readonly(); } - if elf_flags.contains(ElfSectionFlags::EXECUTABLE) { flags = flags.execute(); } - flags -} \ No newline at end of file diff --git a/kernel/src/arch/x86_64/mod.rs b/kernel/src/arch/x86_64/mod.rs index 9d1ed17..d1868f7 100644 --- a/kernel/src/arch/x86_64/mod.rs +++ b/kernel/src/arch/x86_64/mod.rs @@ -1,6 +1,6 @@ -extern crate multiboot2; +extern crate bootloader; -use memory::MemorySet; +use self::bootloader::bootinfo::{BootInfo, MemoryRegionType}; pub mod driver; pub mod cpu; @@ -8,20 +8,31 @@ pub mod interrupt; pub mod paging; pub mod gdt; pub mod idt; -pub mod smp; +// TODO: Move multi-core init to bootloader +//pub mod smp; pub mod memory; pub mod io; -pub fn init() { +/// The entry point of kernel +#[no_mangle] // don't mangle the name of this function +pub extern "C" fn _start(boot_info: &'static BootInfo) -> ! { + // First init log mod, so that we can print log info. + ::logging::init(); + info!("Hello world!"); + info!("{:#?}", boot_info); + + // Init trap handling. idt::init(); - let boot_info_addr = unsafe { *(0 as *const u32).offset(-1) } as usize; - let boot_info = unsafe { multiboot2::load(boot_info_addr) }; - let rsdt_addr = boot_info.rsdp_v1_tag().unwrap().rsdt_address(); + + // Init physical memory management and heap. memory::init(boot_info); + // Now heap is available gdt::init(); - let acpi = driver::init(rsdt_addr); - smp::start_other_cores(&acpi); + + driver::init(); + + ::kmain(); } /// The entry point for another processors @@ -31,7 +42,7 @@ pub extern "C" fn other_main() -> ! { gdt::init(); driver::apic::other_init(); let cpu_id = driver::apic::lapic_id(); - let ms = unsafe { smp::notify_started(cpu_id) }; +// let ms = unsafe { smp::notify_started(cpu_id) }; println!("Hello world! from CPU {}!", cpu_id); // unsafe{ let a = *(0xdeadbeaf as *const u8); } // Page fault loop {} diff --git a/kernel/src/lang.rs b/kernel/src/lang.rs index ba7d060..a289ccc 100644 --- a/kernel/src/lang.rs +++ b/kernel/src/lang.rs @@ -7,7 +7,7 @@ use core::alloc::Layout; extern fn eh_personality() { } -#[panic_implementation] +#[panic_handler] #[no_mangle] pub fn panic(info: &PanicInfo) -> ! { let location = info.location().unwrap(); diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index a129cc0..4a23294 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -2,14 +2,10 @@ #![feature(lang_items)] #![feature(const_fn)] #![feature(alloc)] -#![feature(allocator_api)] -#![feature(abi_x86_interrupt)] -#![feature(iterator_step_by)] -#![feature(unboxed_closures)] #![feature(naked_functions)] #![feature(asm)] #![feature(optin_builtin_traits)] -#![feature(panic_implementation)] +#![feature(panic_handler)] #![feature(panic_info_message)] #![feature(global_asm)] #![feature(compiler_builtins_lib)] @@ -64,14 +60,7 @@ pub mod arch; #[path = "arch/riscv32/mod.rs"] pub mod arch; -/// The entry point of Rust kernel -#[no_mangle] -pub extern "C" fn rust_main() -> ! { - // ATTENTION: we have a very small stack and no guard page - println!("Hello World{}", "!"); - - logging::init(); - arch::init(); +pub fn kmain() -> ! { process::init(); unsafe { arch::interrupt::enable(); } diff --git a/kernel/src/main.rs b/kernel/src/main.rs index 22852b6..8f0dad8 100644 --- a/kernel/src/main.rs +++ b/kernel/src/main.rs @@ -4,10 +4,3 @@ #[macro_use] extern crate ucore; - -#[cfg(not(test))] -#[cfg(target_arch = "x86_64")] -#[no_mangle] // don't mangle the name of this function -pub extern "C" fn _start() -> ! { - ucore::rust_main(); -} \ No newline at end of file diff --git a/kernel/src/memory.rs b/kernel/src/memory.rs index 3f88ff0..0f203f3 100644 --- a/kernel/src/memory.rs +++ b/kernel/src/memory.rs @@ -1,5 +1,5 @@ pub use arch::paging::*; -use bit_allocator::{BitAlloc, BitAlloc4K}; +use bit_allocator::{BitAlloc, BitAlloc4K, BitAlloc64K}; use consts::MEMORY_OFFSET; use spin::{Mutex, MutexGuard}; use super::HEAP_ALLOCATOR; @@ -9,8 +9,16 @@ pub use ucore_memory::memory_set::{MemoryArea, MemoryAttr, MemorySet as MemorySe pub type MemorySet = MemorySet_; +// x86_64 support up to 256M memory +#[cfg(target_arch = "x86_64")] +pub type FrameAlloc = BitAlloc64K; + +// RISCV only have 8M memory +#[cfg(target_arch = "riscv32")] +pub type FrameAlloc = BitAlloc4K; + lazy_static! { - pub static ref FRAME_ALLOCATOR: Mutex = Mutex::new(BitAlloc4K::default()); + pub static ref FRAME_ALLOCATOR: Mutex = Mutex::new(FrameAlloc::default()); } pub fn alloc_frame() -> Option { @@ -52,8 +60,9 @@ pub fn page_fault_handler(addr: usize) -> bool { } pub fn init_heap() { - use consts::{KERNEL_HEAP_OFFSET, KERNEL_HEAP_SIZE}; - unsafe { HEAP_ALLOCATOR.lock().init(KERNEL_HEAP_OFFSET, KERNEL_HEAP_SIZE); } + use consts::KERNEL_HEAP_SIZE; + static mut HEAP: [u8; KERNEL_HEAP_SIZE] = [0; KERNEL_HEAP_SIZE]; + unsafe { HEAP_ALLOCATOR.lock().init(HEAP.as_ptr() as usize, KERNEL_HEAP_SIZE); } info!("heap init end"); } diff --git a/kernel/src/util.rs b/kernel/src/util.rs index f8ad1a1..1629386 100644 --- a/kernel/src/util.rs +++ b/kernel/src/util.rs @@ -1,26 +1,5 @@ use core::fmt::Debug; -pub fn bytes_sum(p: &T) -> u8 { - use core::mem::size_of_val; - let len = size_of_val(p); - let p = p as *const T as *const u8; - (0..len).map(|i| unsafe { &*p.offset(i as isize) }) - .fold(0, |a, &b| a.overflowing_add(b).0) -} - -/// -pub trait Checkable { - fn check(&self) -> bool; -} - -/// Scan memory to find the struct -pub unsafe fn find_in_memory - (begin: usize, len: usize, step: usize) -> Option { - - (begin .. begin + len).step_by(step) - .find(|&addr| { (&*(addr as *const T)).check() }) -} - /// Convert C string to Rust string pub unsafe fn from_cstr(s: *const u8) -> &'static str { use core::{str, slice};