Skip to content
Snippets Groups Projects
Verified Commit 05ac036f authored by Jeremy Soller's avatar Jeremy Soller
Browse files

Add logging and implement opening RedoxFS

parent cb8a10ca
No related branches found
No related tags found
No related merge requests found
......@@ -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"
......
......@@ -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"
......
......@@ -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
......
......@@ -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))
}
}
......@@ -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;
}
......
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) {}
}
......@@ -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(())
......
......@@ -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:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment