Add logging and implement opening RedoxFS

This commit is contained in:
Jeremy Soller
2022-02-02 20:40:27 -07:00
parent cb8a10ca26
commit 05ac036f52
8 changed files with 150 additions and 38 deletions
Generated
+12 -1
View File
@@ -98,8 +98,10 @@ name = "redox_bootloader"
version = "0.1.0"
dependencies = [
"linked_list_allocator",
"log",
"redox_syscall",
"redoxfs",
"spin",
]
[[package]]
@@ -114,7 +116,7 @@ dependencies = [
[[package]]
name = "redoxfs"
version = "0.5.0"
source = "git+https://gitlab.redox-os.org/redox-os/redoxfs.git?branch=0.5.0#13d220fe6e954be4bbf7e20ccd117761474ae446"
source = "git+https://gitlab.redox-os.org/redox-os/redoxfs.git?branch=0.5.0#a551f3a0b7ea2b004c62665c2bf4003b49ea7eb6"
dependencies = [
"aes",
"generic-array",
@@ -143,6 +145,15 @@ name = "simple_endian"
version = "0.2.1"
source = "git+https://github.com/michalfita/simple-endian-rs.git?rev=7210f40881d16f7f2e3d8d40f6381fa222843caa#7210f40881d16f7f2e3d8d40f6381fa222843caa"
[[package]]
name = "spin"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "511254be0c5bcf062b019a6c89c01a664aa359ded62f78aa72c6fc137c0590e5"
dependencies = [
"lock_api",
]
[[package]]
name = "spinning_top"
version = "0.2.4"
+2 -1
View File
@@ -8,10 +8,11 @@ name = "bootloader"
path = "src/lib.rs"
crate-type = ["staticlib"]
[dependencies]
linked_list_allocator = "0.9.1"
log = "0.4.14"
redox_syscall = "0.2.10"
spin = "0.9.2"
[dependencies.redoxfs]
git = "https://gitlab.redox-os.org/redox-os/redoxfs.git"
+17 -1
View File
@@ -26,7 +26,22 @@ build/bootloader.bin: build/bootloader.elf $(ARCH)/**
mkdir -p build
nasm -f bin -o $@ -l $@.lst -D STAGE3=$< -i$(ARCH) $(ARCH)/bootloader.asm
build/harddrive.bin: build/bootloader.bin
build/filesystem:
mkdir -p build
rm -f $@.partial
mkdir $@.partial
fallocate -l 1MiB $@.partial/kernel
mv $@.partial $@
build/filesystem.bin: build/filesystem
mkdir -p build
rm -f $@.partial
fallocate -l 255MiB $@.partial
redoxfs-ar $@.partial $<
mv $@.partial $@
build/harddrive.bin: build/bootloader.bin build/filesystem.bin
mkdir -p build
rm -f $@.partial
fallocate -l 256MiB $@.partial
@@ -34,6 +49,7 @@ build/harddrive.bin: build/bootloader.bin
$(PARTED) -s -a minimal $@.partial mkpart primary 1MiB 100%
dd if=$< of=$@.partial bs=1 count=446 conv=notrunc
dd if=$< of=$@.partial bs=512 skip=1 seek=1 conv=notrunc
dd if=build/filesystem.bin of=$@.partial bs=1MiB seek=1 conv=notrunc
mv $@.partial $@
qemu: build/harddrive.bin
+13 -8
View File
@@ -30,12 +30,13 @@ impl DiskAddressPacket {
}
pub struct DiskBios {
boot_disk: u8,
thunk13: extern "C" fn(),
}
impl DiskBios {
pub fn new(thunk13: extern "C" fn()) -> Self {
Self { thunk13 }
pub fn new(boot_disk: u8, thunk13: extern "C" fn()) -> Self {
Self { boot_disk, thunk13 }
}
}
@@ -47,8 +48,7 @@ impl Disk for DiskBios {
let mut data = ThunkData::new();
data.ax = 0x4200;
//TODO: get original drive number!
data.dx = 0x0080;
data.dx = self.boot_disk as u16;
data.si = DISK_ADDRESS_PACKET_ADDR as u16;
data.with(self.thunk13);
@@ -66,12 +66,17 @@ impl Disk for DiskBios {
}
unsafe fn write_at(&mut self, block: u64, buffer: &[u8]) -> Result<usize> {
//TODO
Ok(0)
log::error!(
"DiskBios::write_at(0x{:X}, 0x{:X}:0x{:X}) not allowed",
block,
buffer.as_ptr() as usize,
buffer.len()
);
Err(Error::new(EIO))
}
fn size(&mut self) -> Result<u64> {
//TODO
Ok(0)
log::error!("DiskBios::size not implemented");
Err(Error::new(EIO))
}
}
+57 -17
View File
@@ -14,12 +14,16 @@ use core::{
slice,
};
use linked_list_allocator::LockedHeap;
use log::{error, info};
use self::disk::DiskBios;
use self::logger::LOGGER;
use self::thunk::ThunkData;
use self::vbe::{VbeCardInfo, VbeModeInfo};
use self::vga::{VgaTextBlock, VgaTextColor, Vga};
mod disk;
mod logger;
mod panic;
mod thunk;
mod vbe;
@@ -37,8 +41,11 @@ const VGA_ADDR: usize = 0xB8000;
#[global_allocator]
static ALLOCATOR: LockedHeap = LockedHeap::empty();
static mut VGA: Vga = unsafe { Vga::new(VGA_ADDR as *mut VgaTextBlock, 80, 25) };
#[no_mangle]
pub unsafe extern "C" fn kstart(
boot_disk: usize,
thunk10: extern "C" fn(),
thunk13: extern "C" fn(),
thunk15: extern "C" fn(),
@@ -59,13 +66,15 @@ pub unsafe extern "C" fn kstart(
data.with(thunk10);
}
let mut vga = Vga::new(VGA_ADDR as *mut VgaTextBlock, 80, 25);
for i in 0..vga.blocks.len() {
vga.blocks[i].char = 0;
vga.blocks[i].color =
((VgaTextColor::DarkGray as u8) << 4) |
(VgaTextColor::White as u8);
{
// Clear VGA console
let blocks = VGA.blocks();
for i in 0..blocks.len() {
blocks[i] = VgaTextBlock {
char: 0,
color: ((VGA.bg as u8) << 4) | (VGA.fg as u8),
};
}
}
// Initialize allocator at the end of stage 3 with a meager 1 MiB
@@ -76,6 +85,35 @@ pub unsafe extern "C" fn kstart(
let heap_size = 1024 * 1024;
ALLOCATOR.lock().init(heap_start, heap_size);
// Set logger
LOGGER.init();
// Locate RedoxFS
{
//TODO: ensure boot_disk is 8-bit
info!("DISK {:02X}", boot_disk);
let disk = DiskBios::new(boot_disk as u8, thunk13);
//TODO: get block from partition table
let block = 1024 * 1024 / redoxfs::BLOCK_SIZE;
match redoxfs::FileSystem::open(disk, Some(block), false) {
Ok(mut fs) => {
info!("RedoxFS {} MiB", fs.header.size() / 1024 / 1024);
match fs.tx(|tx| tx.find_node(redoxfs::TreePtr::root(), "kernel")) {
Ok(node) => {
info!("Kernel {} MiB", node.data().size() / 1024 / 1024);
},
Err(err) => {
error!("Failed to find kernel file: {:?}", err);
}
}
},
Err(err) => {
error!("Failed to open RedoxFS: {:?}", err);
}
}
}
let mut modes = Vec::new();
{
// Get card info
@@ -133,20 +171,22 @@ pub unsafe extern "C" fn kstart(
format!("{:>4}x{:<4} {:>3}:{:<3}", w, h, aspect_w, aspect_h)
));
} else {
writeln!(vga, "Failed to read VBE mode 0x{:04X} info: 0x{:04X}", mode, data.ax);
error!("Failed to read VBE mode 0x{:04X} info: 0x{:04X}", mode, data.ax);
}
}
} else {
writeln!(vga, "Failed to read VBE card info: 0x{:04X}", data.ax);
error!("Failed to read VBE card info: 0x{:04X}", data.ax);
}
}
// Sort modes by pixel area, reversed
modes.sort_by(|a, b| (b.1 * b.2).cmp(&(a.1 * a.2)));
writeln!(vga, "Arrow keys and space select mode, enter to continue");
writeln!(VGA, "Arrow keys and enter select mode").unwrap();
//TODO 0x4F03 VBE function to get current mode
let off_x = VGA.x;
let off_y = VGA.y;
let rows = 12;
let mut selected = modes.get(0).map_or(0, |x| x.0);
loop {
@@ -158,18 +198,18 @@ pub unsafe extern "C" fn kstart(
row = 0;
}
vga.x = 1 + col * 20;
vga.y = 1 + row;
VGA.x = off_x + col * 20;
VGA.y = off_y + row;
if *mode == selected {
vga.bg = VgaTextColor::White;
vga.fg = VgaTextColor::Black;
VGA.bg = VgaTextColor::White;
VGA.fg = VgaTextColor::Black;
} else {
vga.bg = VgaTextColor::DarkGray;
vga.fg = VgaTextColor::White;
VGA.bg = VgaTextColor::DarkGray;
VGA.fg = VgaTextColor::White;
}
write!(vga, "{}", text);
write!(VGA, "{}", text).unwrap();
row += 1;
}
+31
View File
@@ -0,0 +1,31 @@
use core::fmt::Write;
use log::{Level, LevelFilter, Log, Metadata, Record, SetLoggerError};
use crate::VGA;
pub static LOGGER: Logger = Logger;
pub struct Logger;
impl Logger {
pub fn init(&'static self) {
log::set_logger(self).unwrap();
log::set_max_level(LevelFilter::Info);
}
}
impl Log for Logger {
fn enabled(&self, metadata: &Metadata) -> bool {
true
}
fn log(&self, record: &Record) {
if self.enabled(record.metadata()) {
unsafe {
writeln!(VGA, "{} - {}", record.level(), record.args()).unwrap();
}
}
}
fn flush(&self) {}
}
+15 -10
View File
@@ -29,7 +29,7 @@ pub enum VgaTextColor {
}
pub struct Vga {
pub blocks: &'static mut [VgaTextBlock],
pub ptr: *mut VgaTextBlock,
pub width: usize,
pub height: usize,
pub x: usize,
@@ -39,12 +39,9 @@ pub struct Vga {
}
impl Vga {
pub unsafe fn new(ptr: *mut VgaTextBlock, width: usize, height: usize) -> Self {
pub const unsafe fn new(ptr: *mut VgaTextBlock, width: usize, height: usize) -> Self {
Self {
blocks: slice::from_raw_parts_mut(
ptr,
width * height
),
ptr,
width,
height,
x: 0,
@@ -53,10 +50,18 @@ impl Vga {
fg: VgaTextColor::White,
}
}
pub unsafe fn blocks(&mut self) -> &'static mut [VgaTextBlock] {
slice::from_raw_parts_mut(
self.ptr,
self.width * self.height,
)
}
}
impl fmt::Write for Vga {
fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> {
let mut blocks = unsafe { self.blocks() };
for c in s.chars() {
if self.x >= self.width {
self.x = 0;
@@ -67,9 +72,9 @@ impl fmt::Write for Vga {
for x in 0..self.width {
let i = y * self.width + x;
let j = i - self.width;
self.blocks[j] = self.blocks[i];
blocks[j] = blocks[i];
if y + 1 == self.height {
self.blocks[i].char = 0;
blocks[i].char = 0;
}
}
}
@@ -85,15 +90,15 @@ impl fmt::Write for Vga {
},
_ => {
let i = self.y * self.width + self.x;
if let Some(block) = self.blocks.get_mut(i) {
if let Some(block) = blocks.get_mut(i) {
block.char = c as u8;
block.color =
((self.bg as u8) << 4) |
(self.fg as u8);
}
self.x += 1;
}
}
self.x += 1;
}
Ok(())
+3
View File
@@ -130,6 +130,9 @@ protected_mode:
push eax
mov eax, thunk.int10
push eax
xor eax, eax
mov al, [disk]
push eax
mov eax, [args.stage3_base]
call [eax + 0x18]
.halt: