This commit is contained in:
parent
38993dc42d
commit
7a47fbaea8
8 changed files with 38 additions and 8 deletions
10
Cargo.lock
generated
10
Cargo.lock
generated
|
@ -204,6 +204,7 @@ dependencies = [
|
||||||
"elf",
|
"elf",
|
||||||
"kernel-common",
|
"kernel-common",
|
||||||
"log",
|
"log",
|
||||||
|
"raw-cpuid",
|
||||||
"static-alloc",
|
"static-alloc",
|
||||||
"uefi",
|
"uefi",
|
||||||
]
|
]
|
||||||
|
@ -300,6 +301,15 @@ version = "0.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
|
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "raw-cpuid"
|
||||||
|
version = "11.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1ab240315c661615f2ee9f0f2cd32d5a7343a84d5ebcccb99d46e6637565e7b0"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.11.1"
|
version = "1.11.1"
|
||||||
|
|
|
@ -38,6 +38,7 @@ static LOADER_STRUCT: Mutex<LoaderStruct> = Mutex::new(LoaderStruct {
|
||||||
phys_heap_start: 0,
|
phys_heap_start: 0,
|
||||||
rsdp_address: 0,
|
rsdp_address: 0,
|
||||||
available_memory: [LoaderStructMemoryRegion { initial_page: 0, page_count: 0 }; 1024],
|
available_memory: [LoaderStructMemoryRegion { initial_page: 0, page_count: 0 }; 1024],
|
||||||
|
vm: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
global_asm!(include_str!("cpu/boot.s"), options(att_syntax));
|
global_asm!(include_str!("cpu/boot.s"), options(att_syntax));
|
||||||
|
@ -47,13 +48,13 @@ extern "C" fn early_main(temp_loader_struct: *const LoaderStruct) -> ! {
|
||||||
unsafe {
|
unsafe {
|
||||||
ALLOC.lock().init(KERNEL_HEAP_START as usize, KERNEL_HEAP_INITIAL_SIZE);
|
ALLOC.lock().init(KERNEL_HEAP_START as usize, KERNEL_HEAP_INITIAL_SIZE);
|
||||||
}
|
}
|
||||||
init_logger();
|
|
||||||
info!("Starting kernel...");
|
|
||||||
let mut loader_struct = LOADER_STRUCT.lock();
|
let mut loader_struct = LOADER_STRUCT.lock();
|
||||||
unsafe {
|
unsafe {
|
||||||
temp_loader_struct.copy_to(&mut *loader_struct, 1);
|
temp_loader_struct.copy_to(&mut *loader_struct, 1);
|
||||||
}
|
}
|
||||||
assert_eq!(loader_struct.magic, LOADER_STRUCT_MAGIC);
|
assert_eq!(loader_struct.magic, LOADER_STRUCT_MAGIC);
|
||||||
|
init_logger(loader_struct.vm != 0);
|
||||||
|
info!("Starting kernel...");
|
||||||
setup_gdt();
|
setup_gdt();
|
||||||
setup_idt();
|
setup_idt();
|
||||||
setup_paging(&loader_struct, loader_struct.phys_kernel_start, loader_struct.phys_heap_start);
|
setup_paging(&loader_struct, loader_struct.phys_kernel_start, loader_struct.phys_heap_start);
|
||||||
|
|
|
@ -12,6 +12,7 @@ pub struct LoaderStruct {
|
||||||
pub phys_heap_start: u64,
|
pub phys_heap_start: u64,
|
||||||
pub rsdp_address: u64,
|
pub rsdp_address: u64,
|
||||||
pub available_memory: [LoaderStructMemoryRegion; 1024],
|
pub available_memory: [LoaderStructMemoryRegion; 1024],
|
||||||
|
pub vm: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const LOADER_STRUCT_MAGIC: u64 = 0x123456789abcdef0;
|
pub const LOADER_STRUCT_MAGIC: u64 = 0x123456789abcdef0;
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
use core::fmt::{Result, Write};
|
use core::{
|
||||||
|
fmt::{Result, Write},
|
||||||
|
sync::atomic::{AtomicBool, Ordering},
|
||||||
|
};
|
||||||
|
|
||||||
use log::{LevelFilter, Log, Metadata};
|
use log::{LevelFilter, Log, Metadata};
|
||||||
|
|
||||||
|
@ -8,9 +11,13 @@ struct SerialWriter;
|
||||||
pub struct SerialLogger;
|
pub struct SerialLogger;
|
||||||
|
|
||||||
static LOGGER: SerialLogger = SerialLogger {};
|
static LOGGER: SerialLogger = SerialLogger {};
|
||||||
|
static SERIAL_ENABLED: AtomicBool = AtomicBool::new(false);
|
||||||
|
|
||||||
impl Write for SerialWriter {
|
impl Write for SerialWriter {
|
||||||
fn write_str(&mut self, s: &str) -> Result {
|
fn write_str(&mut self, s: &str) -> Result {
|
||||||
|
if !SERIAL_ENABLED.load(Ordering::SeqCst) {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
for byte in s.bytes() {
|
for byte in s.bytes() {
|
||||||
unsafe {
|
unsafe {
|
||||||
outb(0x3f8, byte);
|
outb(0x3f8, byte);
|
||||||
|
@ -30,7 +37,8 @@ impl Log for SerialLogger {
|
||||||
fn flush(&self) {}
|
fn flush(&self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init_logger() {
|
pub fn init_logger(serial_enabled: bool) {
|
||||||
|
SERIAL_ENABLED.store(serial_enabled, Ordering::SeqCst);
|
||||||
log::set_logger(&LOGGER).unwrap();
|
log::set_logger(&LOGGER).unwrap();
|
||||||
log::set_max_level(LevelFilter::Trace);
|
log::set_max_level(LevelFilter::Trace);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,5 +8,6 @@ license = "Unlicense"
|
||||||
elf = {version = "0.7.4", default-features = false}
|
elf = {version = "0.7.4", default-features = false}
|
||||||
kernel-common = {path = "../lib/kernel-common"}
|
kernel-common = {path = "../lib/kernel-common"}
|
||||||
log = "0.4.22"
|
log = "0.4.22"
|
||||||
|
raw-cpuid = "11.2.0"
|
||||||
static-alloc = "0.2.5"
|
static-alloc = "0.2.5"
|
||||||
uefi = "0.33.0"
|
uefi = "0.33.0"
|
||||||
|
|
|
@ -4,13 +4,14 @@ use uefi::{
|
||||||
mem::memory_map::{MemoryMap, MemoryMapOwned},
|
mem::memory_map::{MemoryMap, MemoryMapOwned},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn generate_loader_struct(memory_map: &MemoryMapOwned, phys_start: u64, heap_start: u64, rsdp_address: u64) -> LoaderStruct {
|
pub fn generate_loader_struct(memory_map: &MemoryMapOwned, phys_start: u64, heap_start: u64, rsdp_address: u64, vm: bool) -> LoaderStruct {
|
||||||
let mut loader_struct = LoaderStruct {
|
let mut loader_struct = LoaderStruct {
|
||||||
magic: LOADER_STRUCT_MAGIC,
|
magic: LOADER_STRUCT_MAGIC,
|
||||||
phys_kernel_start: phys_start,
|
phys_kernel_start: phys_start,
|
||||||
phys_heap_start: heap_start,
|
phys_heap_start: heap_start,
|
||||||
rsdp_address,
|
rsdp_address,
|
||||||
available_memory: [LoaderStructMemoryRegion { initial_page: 0, page_count: 0 }; 1024],
|
available_memory: [LoaderStructMemoryRegion { initial_page: 0, page_count: 0 }; 1024],
|
||||||
|
vm: vm as u8,
|
||||||
};
|
};
|
||||||
let mut next_entry = 0;
|
let mut next_entry = 0;
|
||||||
for i in memory_map.entries() {
|
for i in memory_map.entries() {
|
||||||
|
|
|
@ -20,6 +20,7 @@ use kernel_common::{
|
||||||
use loader_struct::generate_loader_struct;
|
use loader_struct::generate_loader_struct;
|
||||||
use log::{error, info};
|
use log::{error, info};
|
||||||
use paging::setup_paging;
|
use paging::setup_paging;
|
||||||
|
use raw_cpuid::CpuId;
|
||||||
use static_alloc::Bump;
|
use static_alloc::Bump;
|
||||||
use uefi::{
|
use uefi::{
|
||||||
boot::{allocate_pages, exit_boot_services},
|
boot::{allocate_pages, exit_boot_services},
|
||||||
|
@ -40,9 +41,16 @@ const KERNEL: &[u8] = include_bytes!("../../target/x86_64-unknown-none/release/k
|
||||||
|
|
||||||
#[entry]
|
#[entry]
|
||||||
fn main() -> Status {
|
fn main() -> Status {
|
||||||
init_logger();
|
let cpuid = CpuId::new();
|
||||||
|
let features = cpuid.get_feature_info().unwrap();
|
||||||
|
init_logger(features.has_hypervisor());
|
||||||
info!("Starting bootloader...");
|
info!("Starting bootloader...");
|
||||||
uefi::helpers::init().unwrap();
|
uefi::helpers::init().unwrap();
|
||||||
|
assert!(features.has_rdrand());
|
||||||
|
let extended_features = cpuid.get_extended_feature_info().unwrap();
|
||||||
|
assert!(extended_features.has_smap());
|
||||||
|
assert!(extended_features.has_smep());
|
||||||
|
assert!(cpuid.get_extended_processor_and_feature_identifiers().unwrap().has_syscall_sysret());
|
||||||
let (kernel_start, kernel_entry) = load_kernel(KERNEL);
|
let (kernel_start, kernel_entry) = load_kernel(KERNEL);
|
||||||
let heap_start = allocate_pages(AllocateType::AnyPages, MemoryType::LOADER_DATA, KERNEL_HEAP_INITIAL_SIZE / 0x1000).unwrap().as_ptr() as u64;
|
let heap_start = allocate_pages(AllocateType::AnyPages, MemoryType::LOADER_DATA, KERNEL_HEAP_INITIAL_SIZE / 0x1000).unwrap().as_ptr() as u64;
|
||||||
let rsdp = AtomicU64::new(0);
|
let rsdp = AtomicU64::new(0);
|
||||||
|
@ -58,7 +66,7 @@ fn main() -> Status {
|
||||||
let memory_map = unsafe { exit_boot_services(MemoryType::LOADER_DATA) };
|
let memory_map = unsafe { exit_boot_services(MemoryType::LOADER_DATA) };
|
||||||
let pml4 = setup_paging(&memory_map, heap_start);
|
let pml4 = setup_paging(&memory_map, heap_start);
|
||||||
map_kernel(KERNEL, pml4, kernel_start);
|
map_kernel(KERNEL, pml4, kernel_start);
|
||||||
let loader_struct = generate_loader_struct(&memory_map, kernel_start, heap_start, rsdp.load(Ordering::SeqCst));
|
let loader_struct = generate_loader_struct(&memory_map, kernel_start, heap_start, rsdp.load(Ordering::SeqCst), features.has_hypervisor());
|
||||||
info!("Jumping to kernel...");
|
info!("Jumping to kernel...");
|
||||||
unsafe {
|
unsafe {
|
||||||
(mem::transmute::<_, extern "C" fn(&LoaderStruct) -> !>(kernel_entry))(&loader_struct);
|
(mem::transmute::<_, extern "C" fn(&LoaderStruct) -> !>(kernel_entry))(&loader_struct);
|
||||||
|
|
2
qemu.sh
2
qemu.sh
|
@ -2,4 +2,4 @@
|
||||||
# shellcheck disable=SC2068
|
# shellcheck disable=SC2068
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
./build.sh
|
./build.sh
|
||||||
qemu-system-x86_64 -M q35 -accel kvm -cpu qemu64,+rdrand -m 256M -L /usr/share/OVMF -bios OVMF_CODE.fd -drive file=img/os.img,format=raw $@
|
qemu-system-x86_64 -M q35 -accel kvm -cpu qemu64,rdrand,smap,smep -m 256M -L /usr/share/OVMF -bios OVMF_CODE.fd -drive file=img/os.img,format=raw $@
|
||||||
|
|
Loading…
Add table
Reference in a new issue