Skip to content
Snippets Groups Projects
Commit 71dd03be authored by Deepak Sirone's avatar Deepak Sirone
Browse files

Read bootsector

parent 838c09e1
No related branches found
No related tags found
No related merge requests found
...@@ -8,6 +8,11 @@ name = "bitflags" ...@@ -8,6 +8,11 @@ name = "bitflags"
version = "1.0.3" version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "byteorder"
version = "1.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.0.17" version = "1.0.17"
...@@ -35,6 +40,7 @@ name = "pamb_os" ...@@ -35,6 +40,7 @@ name = "pamb_os"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"goblin 0.0.10 (registry+https://github.com/rust-lang/crates.io-index)", "goblin 0.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
"linked_list_allocator 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "linked_list_allocator 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"raw-cpuid 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "raw-cpuid 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
...@@ -105,6 +111,7 @@ dependencies = [ ...@@ -105,6 +111,7 @@ dependencies = [
[metadata] [metadata]
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
"checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789" "checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789"
"checksum byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "74c0b906e9446b0a2e4f760cdb3fa4b2c48cdc6db8766a845c54b6ff063fd2e9"
"checksum cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "49ec142f5768efb5b7622aebc3fdbdbb8950a4b9ba996393cb76ef7466e8747d" "checksum cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "49ec142f5768efb5b7622aebc3fdbdbb8950a4b9ba996393cb76ef7466e8747d"
"checksum goblin 0.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "81af14056c25d33759862c5ae2035452acb1255bfb1b16db57819f183921e259" "checksum goblin 0.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "81af14056c25d33759862c5ae2035452acb1255bfb1b16db57819f183921e259"
"checksum linked_list_allocator 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1ee3eeeadfa301cf51b59684c034ad47a9796d03a8b70650d46b6b400a4a3258" "checksum linked_list_allocator 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1ee3eeeadfa301cf51b59684c034ad47a9796d03a8b70650d46b6b400a4a3258"
......
...@@ -14,6 +14,7 @@ linked_list_allocator = "0.6.1" ...@@ -14,6 +14,7 @@ linked_list_allocator = "0.6.1"
slab_allocator = { path = "slab_allocator" , optional = true} slab_allocator = { path = "slab_allocator" , optional = true}
raw-cpuid = "3.0" raw-cpuid = "3.0"
redox_syscall = { path = "syscall"} redox_syscall = { path = "syscall"}
byteorder = { version = "1", default-features = false }
[profile.dev] [profile.dev]
panic = "abort" panic = "abort"
......
...@@ -20,6 +20,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ...@@ -20,6 +20,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
This project is based on the Redox kernel.
Link: https://gitlab.redox-os.org/redox-os/kernel
The license for the Redox kernel is as follows:
MIT License MIT License
Copyright (c) 2017 Jeremy Soller Copyright (c) 2017 Jeremy Soller
......
...@@ -18,6 +18,7 @@ use idt; ...@@ -18,6 +18,7 @@ use idt;
use interrupt; use interrupt;
use memory; use memory;
use paging; use paging;
use paging::ActivePageTable;
/// Test of zero values in BSS. /// Test of zero values in BSS.
static BSS_TEST_ZERO: usize = 0; static BSS_TEST_ZERO: usize = 0;
...@@ -48,7 +49,7 @@ pub struct KernelArgs { ...@@ -48,7 +49,7 @@ pub struct KernelArgs {
/// The entry to Rust, all things must be initialized /// The entry to Rust, all things must be initialized
#[no_mangle] #[no_mangle]
pub unsafe extern fn kstart(args_ptr: *const KernelArgs) { pub unsafe extern fn kstart(args_ptr: *const KernelArgs) -> ActivePageTable {
let env = { let env = {
let args = &*args_ptr; let args = &*args_ptr;
...@@ -131,9 +132,11 @@ pub unsafe extern fn kstart(args_ptr: *const KernelArgs) { ...@@ -131,9 +132,11 @@ pub unsafe extern fn kstart(args_ptr: *const KernelArgs) {
BSP_READY.store(true, Ordering::SeqCst); BSP_READY.store(true, Ordering::SeqCst);
slice::from_raw_parts(env_base as *const u8, env_size) slice::from_raw_parts(env_base as *const u8, env_size);
active_table
}; };
env
// ::kmain(CPU_COUNT.load(Ordering::SeqCst), env); // ::kmain(CPU_COUNT.load(Ordering::SeqCst), env);
} }
......
...@@ -8,15 +8,16 @@ ...@@ -8,15 +8,16 @@
#![feature(naked_functions)] #![feature(naked_functions)]
#![feature(thread_local)] #![feature(thread_local)]
#![feature(alloc)] #![feature(alloc)]
//#![feature(allocator_internals)]
//#![default_lib_allocator]
#![feature(allocator_api, heap_api)] #![feature(allocator_api, heap_api)]
#![feature(global_allocator)] #![feature(global_allocator)]
#![feature(core_intrinsics)] #![feature(core_intrinsics)]
#![feature(type_ascription)]
extern crate rlibc; extern crate rlibc;
extern crate spin; extern crate spin;
extern crate syscall; extern crate syscall;
extern crate linked_list_allocator; extern crate linked_list_allocator;
extern crate byteorder;
#[cfg(feature = "slab")] #[cfg(feature = "slab")]
extern crate slab_allocator; extern crate slab_allocator;
...@@ -42,6 +43,7 @@ pub mod allocator; ...@@ -42,6 +43,7 @@ pub mod allocator;
pub mod memory; pub mod memory;
pub mod time; pub mod time;
pub mod elf; pub mod elf;
pub mod partition;
//pub mod paging; //pub mod paging;
pub mod consts; pub mod consts;
pub mod panic; pub mod panic;
...@@ -68,128 +70,13 @@ static ALLOCATOR: allocator::Allocator = allocator::Allocator; ...@@ -68,128 +70,13 @@ static ALLOCATOR: allocator::Allocator = allocator::Allocator;
use core::slice; use core::slice;
use core::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; use core::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
/// Test of zero values in BSS. //pub const BLOCK_SIZE: u64 = 4096;
static BSS_TEST_ZERO: usize = 0;
/// Test of non-zero values in data.
static DATA_TEST_NONZERO: usize = 0xFFFF_FFFF_FFFF_FFFF;
/// Test of zero values in thread BSS
#[thread_local]
static mut TBSS_TEST_ZERO: usize = 0;
/// Test of non-zero values in thread data.
#[thread_local]
static mut TDATA_TEST_NONZERO: usize = 0xFFFF_FFFF_FFFF_FFFF;
pub static KERNEL_BASE: AtomicUsize = ATOMIC_USIZE_INIT;
pub static KERNEL_SIZE: AtomicUsize = ATOMIC_USIZE_INIT;
pub static CPU_COUNT: AtomicUsize = ATOMIC_USIZE_INIT;
pub static AP_READY: AtomicBool = ATOMIC_BOOL_INIT;
pub static BSP_READY: AtomicBool = ATOMIC_BOOL_INIT;
/*
#[repr(packed)]
pub struct KernelArgs {
kernel_base: u64,
kernel_size: u64,
stack_base: u64,
stack_size: u64,
env_base: u64,
env_size: u64,
}
*/
#[no_mangle] #[no_mangle]
pub unsafe extern fn rust_main(args_ptr: *const arch::x86_64::start::KernelArgs) -> ! pub unsafe extern fn rust_main(args_ptr: *const arch::x86_64::start::KernelArgs) -> !
{ {
arch::x86_64::start::kstart(args_ptr); let mut active_table = arch::x86_64::start::kstart(args_ptr);
// vga_buffer::clear_screen(); let mut mbr = partition::read_bootsector(&mut active_table);
/* let env = {
let args = &*args_ptr;
let kernel_base = args.kernel_base as usize;
let kernel_size = args.kernel_size as usize;
let stack_base = args.stack_base as usize;
let stack_size = args.stack_size as usize;
let env_base = args.env_base as usize;
let env_size = args.env_size as usize;
// BSS should already be zero
{
assert_eq!(BSS_TEST_ZERO, 0);
assert_eq!(DATA_TEST_NONZERO, 0xFFFF_FFFF_FFFF_FFFF);
}
KERNEL_BASE.store(kernel_base, Ordering::SeqCst);
KERNEL_SIZE.store(kernel_size, Ordering::SeqCst);
println!("Kernel: {:X}:{:X}", kernel_base, kernel_base + kernel_size);
println!("Stack: {:X}:{:X}", stack_base, stack_base + stack_size);
println!("Env: {:X}:{:X}", env_base, env_base + env_size);
// Set up GDT before paging
gdt::init();
};*/
/* // Set up IDT before paging
idt::init();
// Initialize memory management
memory::init(0, kernel_base + ((kernel_size + 4095)/4096) * 4096);
// Initialize paging
let (mut active_table, tcb_offset) = paging::init(0, kernel_base, kernel_base + kernel_size, stack_base, stack_base + stack_size);
// Set up GDT after paging with TLS
gdt::init_paging(tcb_offset, stack_base + stack_size);
// Set up IDT
idt::init_paging();
// Test tdata and tbss
{
assert_eq!(TBSS_TEST_ZERO, 0);
TBSS_TEST_ZERO += 1;
assert_eq!(TBSS_TEST_ZERO, 1);
assert_eq!(TDATA_TEST_NONZERO, 0xFFFF_FFFF_FFFF_FFFF);
TDATA_TEST_NONZERO -= 1;
assert_eq!(TDATA_TEST_NONZERO, 0xFFFF_FFFF_FFFF_FFFE);
}
// Reset AP variables
CPU_COUNT.store(1, Ordering::SeqCst);
AP_READY.store(false, Ordering::SeqCst);
BSP_READY.store(false, Ordering::SeqCst);
// Setup kernel heap
allocator::init(&mut active_table);
// Use graphical debug
#[cfg(feature="graphical_debug")]
graphical_debug::init(&mut active_table);
// Initialize devices
device::init(&mut active_table);
// Read ACPI tables, starts APs
#[cfg(feature = "acpi")]
acpi::init(&mut active_table);
// Initialize all of the non-core devices not otherwise needed to complete initialization
device::init_noncore();
// Initialize memory functions after core has loaded
memory::init_noncore();
// Stop graphical debug
#[cfg(feature="graphical_debug")]
graphical_debug::fini(&mut active_table);
BSP_READY.store(true, Ordering::SeqCst);
slice::from_raw_parts(env_base as *const u8, env_size)
};
serial::init();
*/
println!("Hello World!"); println!("Hello World!");
println!("Loader Stub Initialized"); println!("Loader Stub Initialized");
......
use byteorder::{LittleEndian, ByteOrder};
use core::{slice, mem};
use core::ops::{Deref, DerefMut};
use paging::PAGE_SIZE;
#[repr(packed)]
#[derive(Copy, Clone)]
pub struct MbrTableEntry
{
data: [u8; 16]
}
#[repr(packed)]
#[derive(Copy, Clone)]
pub struct Mbr
{
/// The bootstrap code, last 10 bytes can be used as the uuid
pub code: [u8; 446],
/// The partition partition table
pub partition_table: [MbrTableEntry; 4],
/// Signature bytes
pub signature: [u8; 2],
/// Padding
pub padding: [u8; PAGE_SIZE - 512]
}
impl Mbr
{
pub fn default() -> Mbr {
Mbr {
code: [0; 446],
partition_table: [MbrTableEntry::new(); 4],
signature: [0; 2],
padding: [0; PAGE_SIZE - 512]
}
}
pub fn is_valid(&self) -> bool {
self.signature[0] == 0x55 && self.signature[1] == 0xaa
}
}
impl MbrTableEntry
{
pub fn new() -> MbrTableEntry {
MbrTableEntry {
data: [0; 16]
}
}
pub fn is_bootable(&self) -> bool
{
self.data[0] == 0x80
}
pub fn system_id(&self) -> u8
{
self.data[4]
}
pub fn starting_lba(&self) -> u32
{
let mut buf = &self.data[8..12];
LittleEndian::read_u32(&buf)
}
pub fn partition_length(&self) -> u32
{
let mut buf = &self.data[12..16];
LittleEndian::read_u32(&buf)
}
}
impl Deref for MbrTableEntry {
type Target = [u8];
fn deref(&self) -> &[u8] {
unsafe {
slice::from_raw_parts(self as *const MbrTableEntry as *const u8, mem::size_of::<MbrTableEntry>()) as &[u8]
}
}
}
impl DerefMut for MbrTableEntry {
fn deref_mut(&mut self) -> &mut [u8] {
unsafe {
slice::from_raw_parts_mut(self as *mut MbrTableEntry as *mut u8, mem::size_of::<MbrTableEntry>()) as &mut [u8]
}
}
}
use memory::Frame;
use paging::{ActivePageTable, Page, PhysicalAddress, VirtualAddress};
use paging::entry::EntryFlags;
use paging::mapper::MapperFlushAll;
use self::mbr::Mbr;
use paging::PAGE_SIZE;
pub mod mbr;
pub fn read_bootsector(active_table: &mut ActivePageTable) -> Mbr {
let mut mbr = Mbr::default();
let bootsector_addr = 0x7c00;
let follow_up = 0x7c00 + PAGE_SIZE;
let ret;
{
let page = Page::containing_address(VirtualAddress::new(bootsector_addr));
let frame = Frame::containing_address(PhysicalAddress::new(page.start_address().get()));
let result = active_table.map_to(page, frame, EntryFlags::PRESENT | EntryFlags::NO_EXECUTE);
result.flush(active_table);
}
{
let page = Page::containing_address(VirtualAddress::new(follow_up));
let frame = Frame::containing_address(PhysicalAddress::new(page.start_address().get()));
let result = active_table.map_to(page, frame, EntryFlags::PRESENT | EntryFlags::NO_EXECUTE);
result.flush(active_table);
}
{
let bootsector = unsafe { &mut *(bootsector_addr as *mut Mbr) };
ret = bootsector.clone();
println!("Checking if Bootsector is valid: {}", bootsector.is_valid());
}
{
let page = Page::containing_address(VirtualAddress::new(bootsector_addr));
let (result, _frame) = active_table.unmap_return(page, false);
result.flush(active_table);
}
{
let page = Page::containing_address(VirtualAddress::new(follow_up));
let (result, _frame) = active_table.unmap_return(page, false);
result.flush(active_table);
}
ret
}
#[allow(dead_code)]
#[repr(u8)]
#[derive(Clone, Copy)]
pub enum Color {
Black = 0,
Blue = 1,
Green = 2,
Cyan = 3,
Red = 4,
Magenta = 5,
Brown = 6,
LightGray = 7,
DarkGray = 8,
LightBlue = 9,
LightGreen = 10,
LightCyan = 11,
LightRed = 12,
Pink = 13,
Yellow = 14,
White = 15,
}
#[derive(Clone, Copy)]
struct ColorCode(u8);
impl ColorCode {
const fn new(foreground: Color, background: Color) -> ColorCode {
ColorCode((background as u8) << 4 | (foreground as u8))
}
}
#[repr(C)]
#[derive(Copy, Clone)]
struct ScreenChar {
ascii_character: u8,
color_code: ColorCode,
}
const BUFFER_HEIGHT: usize = 25;
const BUFFER_WIDTH: usize = 80;
struct Buffer {
chars: [[ScreenChar; BUFFER_WIDTH]; BUFFER_HEIGHT],
}
use core::ptr::Unique;
pub struct Writer {
column_position: usize,
color_code: ColorCode,
buffer: *mut Buffer,
}
impl Writer {
pub fn write_byte(&mut self, byte: u8) {
match byte {
b'\n' => self.new_line(),
byte => {
if self.column_position >= BUFFER_WIDTH {
self.new_line();
}
let row = BUFFER_HEIGHT - 1;
let col = self.column_position;
self.buffer().chars[row][col] = ScreenChar {
ascii_character: byte,
color_code: self.color_code,
};
self.column_position += 1;
}
}
}
fn buffer(&mut self) -> &mut Buffer {
use core::intrinsics::transmute;
unsafe { transmute::<*mut Buffer, &mut Buffer>(self.buffer) }
}
fn new_line(&mut self) {
for row in 0..(BUFFER_HEIGHT - 1) {
let buffer = self.buffer();
buffer.chars[row] = buffer.chars[row + 1]
}
self.clear_row(BUFFER_HEIGHT - 1);
self.column_position = 0;
}
fn clear_row(&mut self, row: usize) {
let blank = ScreenChar {
ascii_character: b' ',
color_code: self.color_code,
};
self.buffer().chars[row] = [blank; BUFFER_WIDTH];
}
pub fn write_str(&mut self, s: &str) {
for byte in s.bytes() {
self.write_byte(byte)
}
}
}
pub fn print_something() {
let mut writer = Writer {
column_position: 0,
color_code: ColorCode::new(Color::LightGreen, Color::Black),
buffer: unsafe { 0xb8000 as *mut _ }
};
writer.write_byte(b'H');
}
impl ::core::fmt::Write for Writer {
fn write_str(&mut self, s: &str) -> ::core::fmt::Result {
for byte in s.bytes() {
self.write_byte(byte)
}
Ok(())
}
}
use spin::Mutex;
pub static WRITER: Mutex<Writer> = Mutex::new(Writer {
column_position: 0,
color_code: ColorCode::new(Color::LightGreen, Color::Black),
buffer: unsafe { 0xb8000 as *mut _}
});
macro_rules! println {
($fmt:expr) => (print!(concat!($fmt, "\n")));
($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
}
macro_rules! print {
($($arg:tt)*) => ({
use core::fmt::Write;
let mut writer = $crate::vga_buffer::WRITER.lock();
writer.write_fmt(format_args!($($arg)*)).unwrap();
});
}
pub fn clear_screen() {
for _ in 0..BUFFER_HEIGHT {
println!("");
}
}
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