Skip to content

Compile fix #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 0 additions & 13 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,3 @@ notifications:
script:
- RUST_TARGET_PATH=`pwd` xargo build --target x86_64-bootloader --release
- objcopy -O binary -S target/x86_64-bootloader/release/bootloader bootimage.bin

deploy:
provider: script
skip_cleanup: true
on:
repo: rust-osdev/bootloader
tags: true
script:
- |
if [[ "$TRAVIS_TAG" == v* ]]; then
echo "Deploy for $TRAVIS_TAG"
echo "UNIMPLEMENTED!"
fi
57 changes: 35 additions & 22 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
cargo-features = ["publish-lockfile"]

[package]
name = "bootloader"
version = "0.2.0-alpha-004"
version = "0.2.0"
authors = ["Philipp Oppermann <[email protected]>"]
license = "MIT/Apache-2.0"
description = "An experimental pure-Rust x86 bootloader."
publish-lockfile = true

[dependencies]
xmas-elf = "0.6.2"
# x86_64 = "0.2.0-alpha"
x86_64 = { git = "https://github.com/nebulet/x86_64" }
x86_64 = "0.2.7"
usize_conversions = "0.2.0"
# os_bootinfo = "0.2.0"
os_bootinfo = { git = "https://github.com/nebulet/os_bootinfo" }
Expand Down
7 changes: 6 additions & 1 deletion src/boot.s
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ _start:
mov fs, ax
mov gs, ax

# TODO explain
# clear the direction flag (e.g. go forward in memory when using
# instructions like lodsb)
cld


Expand All @@ -29,6 +30,7 @@ enable_a20:
out 0x92, al

enter_protected_mode:
# clear interrupts
cli
push ds
push es
Expand Down Expand Up @@ -118,6 +120,9 @@ println:
print:
cld
print_loop:
# note: if direction flag is set (via std)
# this will DECREMENT the ptr, effectively
# reading/printing in reverse.
lodsb al, BYTE PTR [esi]
test al, al
jz print_done
Expand Down
27 changes: 27 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#![no_std]

extern crate os_bootinfo;

pub mod bootinfo {
pub use os_bootinfo::*;
}

/// Defines the entry point function.
///
/// The function must have the signature `fn(&'static BootInfo) -> !`.
///
/// This macro just creates a function named `_start`, which the linker will use as the entry
/// point. The advantage of using this macro instead of providing an own `_start` function is
/// that the macro ensures that the function and argument types are correct.
#[macro_export]
macro_rules! entry_point {
($path:path) => {
#[export_name = "_start"]
pub extern "C" fn __impl_start(boot_info: &'static $crate::bootinfo::BootInfo) -> ! {
// validate the signature of the program entry point
let f: fn(&'static $crate::bootinfo::BootInfo) -> ! = $path;

f(boot_info)
}
};
}
11 changes: 2 additions & 9 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
#![feature(lang_items)]
#![feature(global_asm)]
#![feature(iterator_step_by)]
#![feature(try_from)]
#![feature(step_trait)]
#![feature(asm)]
#![feature(nll)]
#![feature(pointer_methods)]
#![feature(const_fn)]
#![feature(nll)]
#![feature(panic_implementation)]
#![no_std]
#![no_main]
Expand Down Expand Up @@ -174,9 +171,7 @@ pub extern "C" fn load_elf(
let kernel_end_page: Page<Size2MiB> =
Page::containing_address(kernel_start.virt() + kernel_size - 1u64);
for page in Page::range_inclusive(kernel_start_page, kernel_end_page) {
rec_page_table
.unmap(page)
.expect("dealloc error").1.flush();
rec_page_table.unmap(page).expect("dealloc error").1.flush();
}

// Map kernel segments.
Expand Down Expand Up @@ -252,9 +247,7 @@ fn enable_write_protect_bit() {
#[no_mangle]
pub extern "C" fn panic(info: &PanicInfo) -> ! {
use core::fmt::Write;

let _ = write!(printer::Printer, "{}", info);

write!(printer::Printer, "{}", info).unwrap();
loop {}
}

Expand Down
12 changes: 10 additions & 2 deletions src/page_table.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use fixedvec::FixedVec;
use frame_allocator::FrameAllocator;
use os_bootinfo::MemoryRegionType;
use x86_64::structures::paging::{MapToError, RecursivePageTable, UnmapError};
use x86_64::structures::paging::{self, MapToError, RecursivePageTable, UnmapError};
use x86_64::structures::paging::{Mapper, MapperFlush, Page, PageSize, PageTableFlags, PhysFrame, Size4KiB};
use x86_64::{align_up, PhysAddr, VirtAddr};
use xmas_elf::program::{self, ProgramHeader64};
Expand Down Expand Up @@ -158,5 +158,13 @@ where
S: PageSize,
RecursivePageTable<'a>: Mapper<S>,
{
page_table.map_to(page, phys_frame, flags, frame_allocator)
struct PageTableAllocator<'a, 'b: 'a>(&'a mut FrameAllocator<'b>);

impl<'a, 'b> paging::FrameAllocator<Size4KiB> for PageTableAllocator<'a, 'b> {
fn alloc(&mut self) -> Option<PhysFrame<Size4KiB>> {
self.0.allocate_frame(MemoryRegionType::PageTable)
}
}

page_table.map_to(page, phys_frame, flags, &mut PageTableAllocator(frame_allocator))
}
26 changes: 18 additions & 8 deletions src/second_stage.s
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@ second_stage:
lea si, second_stage_start_str
call println

set_target_operating_mode:
# Some BIOSs assume the processor will only operate in Legacy Mode. We change the Target
# Operating Mode to "Long Mode Target Only", so the firmware expects each CPU to enter Long Mode
# once and then stay in it. This allows the firmware to enable mode-specifc optimizations.
# We save the flags, because CF is set if the callback is not supported (in which case, this is
# a NOP)
pushf
mov ax, 0xec00
mov bl, 0x2
int 0x15
popf

load_kernel_from_disk:
# start of memory buffer
lea eax, _kernel_buffer
Expand Down Expand Up @@ -50,7 +62,11 @@ load_next_kernel_block_from_disk:
push ecx
push esi
mov ecx, 512 / 4
# move with zero extension
# because we are moving a word ptr
# to esi, a 32-bit register.
movzx esi, word ptr [dap_buffer_addr]
# move from esi to edi ecx times.
rep movsd [edi], [esi]
pop esi
pop ecx
Expand All @@ -71,13 +87,7 @@ check_cpu:
call check_cpuid
call check_long_mode

disable_irqs:
mov al, 0xFF # Out 0xFF to 0xA1 and 0x21 to disable all IRQs.
out 0xA1, al
out 0x21, al

nop
nop
cli # disable interrupts

lidt zero_idt # Load a zero length IDT so that any NMI causes a triple fault.

Expand Down Expand Up @@ -250,7 +260,7 @@ gdt_64_pointer:

long_mode:
# call load_elf with kernel start address, size, and memory map as arguments
movabs rdi, 0x400000
movabs rdi, 0x400000 # move absolute 64-bit to register
mov rsi, _kib_kernel_size
lea rdx, _memory_map
movzx rcx, word ptr mmap_ent
Expand Down