From 71dd03bed33266e0f63d7eac8f561e379720ecb0 Mon Sep 17 00:00:00 2001
From: Deepak Sirone <deepaksirone94@gmail.com>
Date: Wed, 20 Jun 2018 23:45:22 +0530
Subject: [PATCH] Read bootsector

---
 Cargo.lock               |   7 ++
 Cargo.toml               |   1 +
 LICENSE                  |   4 +
 src/arch/x86_64/start.rs |   9 ++-
 src/lib.rs               | 129 ++------------------------------
 src/partition/mbr.rs     |  93 +++++++++++++++++++++++
 src/partition/mod.rs     |  54 ++++++++++++++
 src/vga_buffer.rs        | 157 ---------------------------------------
 8 files changed, 173 insertions(+), 281 deletions(-)
 create mode 100755 src/partition/mbr.rs
 create mode 100644 src/partition/mod.rs
 delete mode 100644 src/vga_buffer.rs

diff --git a/Cargo.lock b/Cargo.lock
index d843811..8876d32 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -8,6 +8,11 @@ name = "bitflags"
 version = "1.0.3"
 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]]
 name = "cc"
 version = "1.0.17"
@@ -35,6 +40,7 @@ name = "pamb_os"
 version = "0.1.0"
 dependencies = [
  "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)",
  "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)",
@@ -105,6 +111,7 @@ dependencies = [
 [metadata]
 "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 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 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"
diff --git a/Cargo.toml b/Cargo.toml
index 934bfe5..2c081d7 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -14,6 +14,7 @@ linked_list_allocator = "0.6.1"
 slab_allocator = { path = "slab_allocator" , optional = true}
 raw-cpuid = "3.0"
 redox_syscall = { path = "syscall"}
+byteorder = { version = "1", default-features = false } 
 
 [profile.dev]
 panic = "abort"
diff --git a/LICENSE b/LICENSE
index b19d52d..a9ea7f8 100644
--- a/LICENSE
+++ b/LICENSE
@@ -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
 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
 
 Copyright (c) 2017 Jeremy Soller
diff --git a/src/arch/x86_64/start.rs b/src/arch/x86_64/start.rs
index e5da1dd..dc4ea40 100755
--- a/src/arch/x86_64/start.rs
+++ b/src/arch/x86_64/start.rs
@@ -18,6 +18,7 @@ use idt;
 use interrupt;
 use memory;
 use paging;
+use paging::ActivePageTable;
 
 /// Test of zero values in BSS.
 static BSS_TEST_ZERO: usize = 0;
@@ -48,7 +49,7 @@ pub struct KernelArgs {
 
 /// The entry to Rust, all things must be initialized
 #[no_mangle]
-pub unsafe extern fn kstart(args_ptr: *const KernelArgs)  {
+pub unsafe extern fn kstart(args_ptr: *const KernelArgs) -> ActivePageTable {
     let env = {
         let args = &*args_ptr;
 
@@ -131,9 +132,11 @@ pub unsafe extern fn kstart(args_ptr: *const KernelArgs)  {
 
         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);
 }
 
diff --git a/src/lib.rs b/src/lib.rs
index 4ecdc49..4b69208 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -8,15 +8,16 @@
 #![feature(naked_functions)]
 #![feature(thread_local)]
 #![feature(alloc)]
-//#![feature(allocator_internals)]
-//#![default_lib_allocator]
 #![feature(allocator_api, heap_api)]
 #![feature(global_allocator)]
 #![feature(core_intrinsics)]
+#![feature(type_ascription)]
+
 extern crate rlibc;
 extern crate spin;
 extern crate syscall;
 extern crate linked_list_allocator;
+extern crate byteorder;
 
 #[cfg(feature = "slab")]
 extern crate slab_allocator;
@@ -42,6 +43,7 @@ pub mod allocator;
 pub mod memory;
 pub mod time;
 pub mod elf;
+pub mod partition;
 //pub mod paging;
 pub mod consts;
 pub mod panic;
@@ -68,128 +70,13 @@ static ALLOCATOR: allocator::Allocator = allocator::Allocator;
 use core::slice;
 use core::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
 
-/// Test of zero values in BSS.
-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,
-}
-*/
- 
+//pub const BLOCK_SIZE: u64 = 4096;
+
 #[no_mangle]
 pub unsafe extern fn rust_main(args_ptr: *const arch::x86_64::start::KernelArgs) -> !
 {
-        arch::x86_64::start::kstart(args_ptr);
-//        vga_buffer::clear_screen();
-  /*  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();
-*/
+        let mut active_table  = arch::x86_64::start::kstart(args_ptr);
+        let mut mbr = partition::read_bootsector(&mut active_table);
         println!("Hello World!");
         println!("Loader Stub Initialized");
     
diff --git a/src/partition/mbr.rs b/src/partition/mbr.rs
new file mode 100755
index 0000000..a9bbf4f
--- /dev/null
+++ b/src/partition/mbr.rs
@@ -0,0 +1,93 @@
+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]
+        }
+    }
+}
+
diff --git a/src/partition/mod.rs b/src/partition/mod.rs
new file mode 100644
index 0000000..f80ef63
--- /dev/null
+++ b/src/partition/mod.rs
@@ -0,0 +1,54 @@
+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 
+}
+
diff --git a/src/vga_buffer.rs b/src/vga_buffer.rs
deleted file mode 100644
index 952d545..0000000
--- a/src/vga_buffer.rs
+++ /dev/null
@@ -1,157 +0,0 @@
-#[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!("");
-    }
-}
-
-
-
-
-
-
-- 
GitLab