Only log to serial in a VM
All checks were successful
Build / build (push) Successful in 3m51s

This commit is contained in:
Mathieu Strypsteen 2024-11-11 09:06:58 +01:00
parent 38993dc42d
commit 7a47fbaea8
8 changed files with 38 additions and 8 deletions

10
Cargo.lock generated
View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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