Arm!
This commit is contained in:
parent
c2a95c96d5
commit
6715d5c534
29 changed files with 386 additions and 22 deletions
|
|
@ -9,6 +9,7 @@ crate-type = ["staticlib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bitflags = "*"
|
bitflags = "*"
|
||||||
|
ransid = "*"
|
||||||
spin = "*"
|
spin = "*"
|
||||||
|
|
||||||
[dependencies.goblin]
|
[dependencies.goblin]
|
||||||
|
|
@ -19,6 +20,9 @@ features = ["no_mach", "no_mach32", "no_pe", "no_pe32", "no_endian_fd", "pure"]
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
arch_test = { path = "arch/test" }
|
arch_test = { path = "arch/test" }
|
||||||
|
|
||||||
|
[target.'cfg(target_arch = "arm")'.dependencies]
|
||||||
|
arch_arm = { path = "arch/arm" }
|
||||||
|
|
||||||
[target.'cfg(target_arch = "x86_64")'.dependencies]
|
[target.'cfg(target_arch = "x86_64")'.dependencies]
|
||||||
arch_x86_64 = { path = "arch/x86_64" }
|
arch_x86_64 = { path = "arch/x86_64" }
|
||||||
|
|
||||||
|
|
|
||||||
53
Makefile
53
Makefile
|
|
@ -1,24 +1,27 @@
|
||||||
ARCH?=x86_64
|
ARCH?=arm
|
||||||
|
|
||||||
LD=ld
|
|
||||||
QEMU=qemu-system-$(ARCH)
|
QEMU=qemu-system-$(ARCH)
|
||||||
QEMUFLAGS=-enable-kvm -cpu host
|
QEMUFLAGS=-serial mon:stdio -d guest_errors
|
||||||
|
|
||||||
UNAME := $(shell uname)
|
ifeq ($(ARCH),arm)
|
||||||
ifeq ($(UNAME),Darwin)
|
LD=$(ARCH)-none-eabi-ld
|
||||||
LD=$(ARCH)-elf-ld
|
QEMUFLAGS+=-cpu arm1176 -machine integratorcp
|
||||||
QEMUFLAGS=
|
QEMUFLAGS+=-nographic
|
||||||
|
else
|
||||||
|
LD=ld
|
||||||
|
QEMUFLAGS+=-enable-kvm -cpu host -machine q35 -smp 4
|
||||||
|
#,int,pcall
|
||||||
|
#-nographic
|
||||||
|
#-device intel-iommu
|
||||||
|
|
||||||
|
UNAME := $(shell uname)
|
||||||
|
ifeq ($(UNAME),Darwin)
|
||||||
|
LD=$(ARCH)-elf-ld
|
||||||
|
QEMUFLAGS=
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
QEMUFLAGS+=-smp 4 -machine q35
|
all: build/kernel.bin
|
||||||
QEMUFLAGS+=-serial mon:stdio
|
|
||||||
QEMUFLAGS+=-d guest_errors
|
|
||||||
#,int,pcall
|
|
||||||
#-nographic
|
|
||||||
#-device intel-iommu
|
|
||||||
|
|
||||||
|
|
||||||
all: build/harddrive.bin
|
|
||||||
|
|
||||||
list: build/kernel.list
|
list: build/kernel.list
|
||||||
|
|
||||||
|
|
@ -27,9 +30,6 @@ run: bochs
|
||||||
bochs: build/harddrive.bin
|
bochs: build/harddrive.bin
|
||||||
bochs -f bochs.$(ARCH)
|
bochs -f bochs.$(ARCH)
|
||||||
|
|
||||||
qemu: build/harddrive.bin
|
|
||||||
$(QEMU) $(QEMUFLAGS) -drive file=$<,format=raw,index=0,media=disk
|
|
||||||
|
|
||||||
FORCE:
|
FORCE:
|
||||||
|
|
||||||
build/libcore.rlib: rust/src/libcore/lib.rs
|
build/libcore.rlib: rust/src/libcore/lib.rs
|
||||||
|
|
@ -53,13 +53,24 @@ build/libkernel.a: build/libcore.rlib build/liballoc.rlib build/libcollections.r
|
||||||
RUSTC="./rustc.sh" cargo rustc --target $(ARCH)-unknown-none.json -- -C soft-float -o $@
|
RUSTC="./rustc.sh" cargo rustc --target $(ARCH)-unknown-none.json -- -C soft-float -o $@
|
||||||
|
|
||||||
build/kernel.bin: build/libkernel.a
|
build/kernel.bin: build/libkernel.a
|
||||||
$(LD) --gc-sections -z max-page-size=0x1000 -T bootloader/x86/kernel.ld -o $@ $<
|
$(LD) --gc-sections -z max-page-size=0x1000 -T arch/$(ARCH)/src/linker.ld -o $@ $<
|
||||||
|
|
||||||
|
ifeq ($(ARCH),arm)
|
||||||
|
build/kernel.list: build/kernel.bin
|
||||||
|
$(ARCH)-none-eabi-objdump -C -D $< > $@
|
||||||
|
|
||||||
|
qemu: build/kernel.bin
|
||||||
|
$(QEMU) $(QEMUFLAGS) -kernel $<
|
||||||
|
else
|
||||||
build/kernel.list: build/kernel.bin
|
build/kernel.list: build/kernel.bin
|
||||||
objdump -C -M intel -D $< > $@
|
objdump -C -M intel -D $< > $@
|
||||||
|
|
||||||
build/harddrive.bin: build/kernel.bin
|
build/harddrive.bin: build/kernel.bin
|
||||||
nasm -f bin -o $@ -D ARCH_$(ARCH) -ibootloader/x86/ -ibuild/ bootloader/x86/harddrive.asm
|
nasm -f bin -o $@ -D ARCH_$(ARCH) -ibootloader/$(ARCH)/ -ibuild/ bootloader/$(ARCH)/harddrive.asm
|
||||||
|
|
||||||
|
qemu: build/harddrive.bin
|
||||||
|
$(QEMU) $(QEMUFLAGS) -drive file=$<,format=raw,index=0,media=disk
|
||||||
|
endif
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf build/* target/*
|
rm -rf build/* target/*
|
||||||
|
|
|
||||||
8
arch/arm/Cargo.toml
Normal file
8
arch/arm/Cargo.toml
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
[package]
|
||||||
|
name = "arch_arm"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
bitflags = "*"
|
||||||
|
hole_list_allocator = { path = "../../alloc/hole_list_allocator"}
|
||||||
|
spin = "*"
|
||||||
9
arch/arm/src/context.rs
Normal file
9
arch/arm/src/context.rs
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Context;
|
||||||
|
|
||||||
|
impl Context {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Context
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
70
arch/arm/src/externs.rs
Normal file
70
arch/arm/src/externs.rs
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
/// Memcpy
|
||||||
|
///
|
||||||
|
/// Copy N bytes of memory from one location to another.
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn memcpy(dest: *mut u8, src: *const u8,
|
||||||
|
n: usize) -> *mut u8 {
|
||||||
|
let mut i = 0;
|
||||||
|
while i < n {
|
||||||
|
*dest.offset(i as isize) = *src.offset(i as isize);
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dest
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Memmove
|
||||||
|
///
|
||||||
|
/// Copy N bytes of memory from src to dest. The memory areas may overlap.
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn memmove(dest: *mut u8, src: *const u8,
|
||||||
|
n: usize) -> *mut u8 {
|
||||||
|
if src < dest as *const u8 {
|
||||||
|
let mut i = n;
|
||||||
|
while i != 0 {
|
||||||
|
i -= 1;
|
||||||
|
*dest.offset(i as isize) = *src.offset(i as isize);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let mut i = 0;
|
||||||
|
while i < n {
|
||||||
|
*dest.offset(i as isize) = *src.offset(i as isize);
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dest
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Memset
|
||||||
|
///
|
||||||
|
/// Fill a block of memory with a specified value.
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn memset(s: *mut u8, c: i32, n: usize) -> *mut u8 {
|
||||||
|
let mut i = 0;
|
||||||
|
while i < n {
|
||||||
|
*s.offset(i as isize) = c as u8;
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
s
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Memcmp
|
||||||
|
///
|
||||||
|
/// Compare two blocks of memory.
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32 {
|
||||||
|
let mut i = 0;
|
||||||
|
|
||||||
|
while i < n {
|
||||||
|
let a = *s1.offset(i as isize);
|
||||||
|
let b = *s2.offset(i as isize);
|
||||||
|
if a != b {
|
||||||
|
return a as i32 - b as i32
|
||||||
|
}
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
0
|
||||||
|
}
|
||||||
30
arch/arm/src/interrupt.rs
Normal file
30
arch/arm/src/interrupt.rs
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
//! Interrupt instructions
|
||||||
|
|
||||||
|
/// Clear interrupts
|
||||||
|
#[inline(always)]
|
||||||
|
pub unsafe fn disable() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set interrupts
|
||||||
|
#[inline(always)]
|
||||||
|
pub unsafe fn enable() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set interrupts and halt
|
||||||
|
#[inline(always)]
|
||||||
|
pub unsafe fn enable_and_halt() {
|
||||||
|
halt();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Halt instruction
|
||||||
|
#[inline(always)]
|
||||||
|
pub unsafe fn halt() {
|
||||||
|
//asm!("wfi" : : : : "volatile");
|
||||||
|
asm!("nop" : : : : "volatile");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a stack trace
|
||||||
|
//TODO: Check for stack being mapped before dereferencing
|
||||||
|
#[inline(never)]
|
||||||
|
pub unsafe fn stack_trace() {
|
||||||
|
}
|
||||||
39
arch/arm/src/lib.rs
Normal file
39
arch/arm/src/lib.rs
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
//! Architecture support for ARM
|
||||||
|
|
||||||
|
#![feature(asm)]
|
||||||
|
#![feature(lang_items)]
|
||||||
|
#![feature(naked_functions)]
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
extern crate hole_list_allocator as allocator;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate bitflags;
|
||||||
|
extern crate spin;
|
||||||
|
|
||||||
|
/// Print to console
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! print {
|
||||||
|
($($arg:tt)*) => ({});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Print with new line to console
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! println {
|
||||||
|
($fmt:expr) => (print!(concat!($fmt, "\n")));
|
||||||
|
($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Context switching
|
||||||
|
pub mod context;
|
||||||
|
|
||||||
|
/// Memset, memcpy, etc.
|
||||||
|
pub mod externs;
|
||||||
|
|
||||||
|
/// Interrupt handling
|
||||||
|
pub mod interrupt;
|
||||||
|
|
||||||
|
/// Panic support
|
||||||
|
pub mod panic;
|
||||||
|
|
||||||
|
/// Initialization function
|
||||||
|
pub mod start;
|
||||||
60
arch/arm/src/linker.ld
Normal file
60
arch/arm/src/linker.ld
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
ENTRY(kstart)
|
||||||
|
OUTPUT_ARCH(arm)
|
||||||
|
OUTPUT_FORMAT(elf32-littlearm)
|
||||||
|
|
||||||
|
KERNEL_OFFSET = 0;
|
||||||
|
|
||||||
|
SECTIONS {
|
||||||
|
. = KERNEL_OFFSET;
|
||||||
|
|
||||||
|
.text : AT(ADDR(.text) - KERNEL_OFFSET) {
|
||||||
|
__text_start = .;
|
||||||
|
*(.text*)
|
||||||
|
. = ALIGN(4096);
|
||||||
|
__text_end = .;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rodata : AT(ADDR(.rodata) - KERNEL_OFFSET) {
|
||||||
|
__rodata_start = .;
|
||||||
|
*(.rodata*)
|
||||||
|
. = ALIGN(4096);
|
||||||
|
__rodata_end = .;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data : AT(ADDR(.data) - KERNEL_OFFSET) {
|
||||||
|
__data_start = .;
|
||||||
|
*(.data*)
|
||||||
|
. = ALIGN(4096);
|
||||||
|
__data_end = .;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tdata : AT(ADDR(.tdata) - KERNEL_OFFSET) {
|
||||||
|
__tdata_start = .;
|
||||||
|
*(.tdata*)
|
||||||
|
. = ALIGN(4096);
|
||||||
|
__tdata_end = .;
|
||||||
|
__tbss_start = .;
|
||||||
|
*(.tbss*)
|
||||||
|
. += 8;
|
||||||
|
. = ALIGN(4096);
|
||||||
|
__tbss_end = .;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bss : AT(ADDR(.bss) - KERNEL_OFFSET) {
|
||||||
|
__bss_start = .;
|
||||||
|
*(.bss*)
|
||||||
|
. = ALIGN(4096);
|
||||||
|
__bss_end = .;
|
||||||
|
}
|
||||||
|
|
||||||
|
__end = .;
|
||||||
|
|
||||||
|
/DISCARD/ : {
|
||||||
|
*(.comment*)
|
||||||
|
*(.debug*)
|
||||||
|
*(.eh_frame*)
|
||||||
|
*(.gcc_except_table*)
|
||||||
|
*(.note*)
|
||||||
|
*(.rel.eh_frame*)
|
||||||
|
}
|
||||||
|
}
|
||||||
38
arch/arm/src/panic.rs
Normal file
38
arch/arm/src/panic.rs
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
//! Intrinsics for panic handling
|
||||||
|
|
||||||
|
use interrupt;
|
||||||
|
|
||||||
|
#[cfg(not(test))]
|
||||||
|
#[lang = "eh_personality"]
|
||||||
|
extern "C" fn eh_personality() {}
|
||||||
|
|
||||||
|
#[cfg(not(test))]
|
||||||
|
/// Required to handle panics
|
||||||
|
#[lang = "panic_fmt"]
|
||||||
|
extern "C" fn panic_fmt(fmt: ::core::fmt::Arguments, file: &str, line: u32) -> ! {
|
||||||
|
println!("PANIC: {}", fmt);
|
||||||
|
println!("FILE: {}", file);
|
||||||
|
println!("LINE: {}", line);
|
||||||
|
|
||||||
|
unsafe { interrupt::stack_trace(); }
|
||||||
|
|
||||||
|
println!("HALT");
|
||||||
|
loop {
|
||||||
|
unsafe { interrupt::halt(); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[no_mangle]
|
||||||
|
/// Required to handle panics
|
||||||
|
pub extern "C" fn _Unwind_Resume() -> ! {
|
||||||
|
loop {
|
||||||
|
unsafe { interrupt::halt(); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Required for linker
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn __aeabi_unwind_cpp_pr0() {
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
27
arch/arm/src/start.rs
Normal file
27
arch/arm/src/start.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
const SERIAL_BASE: *mut u8 = 0x16000000 as *mut u8;
|
||||||
|
const SERIAL_FLAG_REGISTER: *const u8 = 0x16000018 as *const u8;
|
||||||
|
const SERIAL_BUFFER_FULL: u8 = (1 << 5);
|
||||||
|
|
||||||
|
unsafe fn putc (c: u8)
|
||||||
|
{
|
||||||
|
/* Wait until the serial buffer is empty */
|
||||||
|
while *SERIAL_FLAG_REGISTER & SERIAL_BUFFER_FULL == SERIAL_BUFFER_FULL {}
|
||||||
|
|
||||||
|
/* Put our character, c, into the serial buffer */
|
||||||
|
*SERIAL_BASE = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn puts(string: &str)
|
||||||
|
{
|
||||||
|
for b in string.bytes() {
|
||||||
|
putc(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
#[naked]
|
||||||
|
pub unsafe extern fn kstart() -> ! {
|
||||||
|
asm!("mov sp, 0x18000" : : : : "volatile");
|
||||||
|
puts("TEST\r\n");
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
62
arch/x86_64/src/linker.ld
Normal file
62
arch/x86_64/src/linker.ld
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
ENTRY(kstart)
|
||||||
|
OUTPUT_FORMAT(elf64-x86-64)
|
||||||
|
|
||||||
|
KERNEL_OFFSET = 0x100000;
|
||||||
|
|
||||||
|
SECTIONS {
|
||||||
|
. = KERNEL_OFFSET;
|
||||||
|
|
||||||
|
. += SIZEOF_HEADERS;
|
||||||
|
. = ALIGN(4096);
|
||||||
|
|
||||||
|
.text : AT(ADDR(.text) - KERNEL_OFFSET) {
|
||||||
|
__text_start = .;
|
||||||
|
*(.text*)
|
||||||
|
. = ALIGN(4096);
|
||||||
|
__text_end = .;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rodata : AT(ADDR(.rodata) - KERNEL_OFFSET) {
|
||||||
|
__rodata_start = .;
|
||||||
|
*(.rodata*)
|
||||||
|
. = ALIGN(4096);
|
||||||
|
__rodata_end = .;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data : AT(ADDR(.data) - KERNEL_OFFSET) {
|
||||||
|
__data_start = .;
|
||||||
|
*(.data*)
|
||||||
|
. = ALIGN(4096);
|
||||||
|
__data_end = .;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tdata : AT(ADDR(.tdata) - KERNEL_OFFSET) {
|
||||||
|
__tdata_start = .;
|
||||||
|
*(.tdata*)
|
||||||
|
. = ALIGN(4096);
|
||||||
|
__tdata_end = .;
|
||||||
|
__tbss_start = .;
|
||||||
|
*(.tbss*)
|
||||||
|
. += 8;
|
||||||
|
. = ALIGN(4096);
|
||||||
|
__tbss_end = .;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bss : AT(ADDR(.bss) - KERNEL_OFFSET) {
|
||||||
|
__bss_start = .;
|
||||||
|
*(.bss*)
|
||||||
|
. = ALIGN(4096);
|
||||||
|
__bss_end = .;
|
||||||
|
}
|
||||||
|
|
||||||
|
__end = .;
|
||||||
|
|
||||||
|
/DISCARD/ : {
|
||||||
|
*(.comment*)
|
||||||
|
*(.debug*)
|
||||||
|
*(.eh_frame*)
|
||||||
|
*(.gcc_except_table*)
|
||||||
|
*(.note*)
|
||||||
|
*(.rel.eh_frame*)
|
||||||
|
}
|
||||||
|
}
|
||||||
25
arm-unknown-none.json
Normal file
25
arm-unknown-none.json
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"llvm-target": "arm-unknown-none",
|
||||||
|
"target-endian": "little",
|
||||||
|
"target-pointer-width": "32",
|
||||||
|
"data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64",
|
||||||
|
"arch": "arm",
|
||||||
|
"os": "none",
|
||||||
|
"env": "",
|
||||||
|
"vendor": "unknown",
|
||||||
|
"target-family": "redox",
|
||||||
|
"pre-link-args": ["-m32", "-nostdlib", "-static"],
|
||||||
|
"features": "+soft-float",
|
||||||
|
"dynamic-linking": false,
|
||||||
|
"executables": false,
|
||||||
|
"relocation-model": "static",
|
||||||
|
"code-model": "kernel",
|
||||||
|
"disable-redzone": true,
|
||||||
|
"eliminate-frame-pointer": false,
|
||||||
|
"exe-suffix": "",
|
||||||
|
"has-rpath": false,
|
||||||
|
"no-compiler-rt": true,
|
||||||
|
"no-default-libraries": true,
|
||||||
|
"position-independent-executables": false,
|
||||||
|
"has-elf-tls": true
|
||||||
|
}
|
||||||
17
bootloader/arm/start.s
Normal file
17
bootloader/arm/start.s
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
interrupt_vector_table:
|
||||||
|
b . @ Reset
|
||||||
|
b .
|
||||||
|
b . @ SWI instruction
|
||||||
|
b .
|
||||||
|
b .
|
||||||
|
b .
|
||||||
|
b .
|
||||||
|
b .
|
||||||
|
|
||||||
|
.comm stack, 0x10000 @ Reserve 64k stack in the BSS
|
||||||
|
_start:
|
||||||
|
.globl _start
|
||||||
|
ldr sp, =stack+0x10000 @ Set up the stack
|
||||||
|
bl kstart @ Jump to the main function
|
||||||
|
1:
|
||||||
|
b 1b @ Halt
|
||||||
131
bootloader/x86_64/bootsector.asm
Normal file
131
bootloader/x86_64/bootsector.asm
Normal file
|
|
@ -0,0 +1,131 @@
|
||||||
|
ORG 0x7C00
|
||||||
|
SECTION .text
|
||||||
|
USE16
|
||||||
|
|
||||||
|
boot: ; dl comes with disk
|
||||||
|
; initialize segment registers
|
||||||
|
xor ax, ax
|
||||||
|
mov ds, ax
|
||||||
|
mov es, ax
|
||||||
|
mov ss, ax
|
||||||
|
|
||||||
|
; initialize stack
|
||||||
|
mov sp, 0x7C00
|
||||||
|
|
||||||
|
mov [disk], dl
|
||||||
|
|
||||||
|
mov si, name
|
||||||
|
call print
|
||||||
|
call print_line
|
||||||
|
|
||||||
|
mov bh, 0
|
||||||
|
mov bl, [disk]
|
||||||
|
call print_num
|
||||||
|
call print_line
|
||||||
|
|
||||||
|
mov ax, (startup_start - boot) / 512
|
||||||
|
mov bx, startup_start
|
||||||
|
mov cx, (startup_end - startup_start) / 512
|
||||||
|
xor dx, dx
|
||||||
|
call load
|
||||||
|
|
||||||
|
mov si, finished
|
||||||
|
call print
|
||||||
|
call print_line
|
||||||
|
|
||||||
|
jmp startup
|
||||||
|
|
||||||
|
; load some sectors from disk to a buffer in memory
|
||||||
|
; buffer has to be below 1MiB
|
||||||
|
; IN
|
||||||
|
; ax: start sector
|
||||||
|
; bx: offset of buffer
|
||||||
|
; cx: number of sectors (512 Bytes each)
|
||||||
|
; dx: segment of buffer
|
||||||
|
; CLOBBER
|
||||||
|
; ax, bx, cx, dx, si
|
||||||
|
; TODO rewrite to (eventually) move larger parts at once
|
||||||
|
; if that is done increase buffer_size_sectors in startup-common to that (max 0x80000 - startup_end)
|
||||||
|
load:
|
||||||
|
cmp cx, 64
|
||||||
|
jbe .good_size
|
||||||
|
|
||||||
|
pusha
|
||||||
|
mov cx, 64
|
||||||
|
call load
|
||||||
|
popa
|
||||||
|
add ax, 64
|
||||||
|
add dx, 64 * 512 / 16
|
||||||
|
sub cx, 64
|
||||||
|
|
||||||
|
jmp load
|
||||||
|
.good_size:
|
||||||
|
mov [DAPACK.addr], ax
|
||||||
|
mov [DAPACK.buf], bx
|
||||||
|
mov [DAPACK.count], cx
|
||||||
|
mov [DAPACK.seg], dx
|
||||||
|
|
||||||
|
mov si, loading
|
||||||
|
call print
|
||||||
|
|
||||||
|
mov bx, [DAPACK.addr]
|
||||||
|
call print_num
|
||||||
|
|
||||||
|
mov al, '#'
|
||||||
|
call print_char
|
||||||
|
|
||||||
|
mov bx, [DAPACK.count]
|
||||||
|
call print_num
|
||||||
|
|
||||||
|
mov al, ' '
|
||||||
|
call print_char
|
||||||
|
|
||||||
|
mov bx, [DAPACK.seg]
|
||||||
|
call print_num
|
||||||
|
|
||||||
|
mov al, ':'
|
||||||
|
call print_char
|
||||||
|
|
||||||
|
mov bx, [DAPACK.buf]
|
||||||
|
call print_num
|
||||||
|
|
||||||
|
call print_line
|
||||||
|
|
||||||
|
mov dl, [disk]
|
||||||
|
mov si, DAPACK
|
||||||
|
mov ah, 0x42
|
||||||
|
int 0x13
|
||||||
|
jc error
|
||||||
|
ret
|
||||||
|
|
||||||
|
error:
|
||||||
|
mov si, errored
|
||||||
|
call print
|
||||||
|
call print_line
|
||||||
|
.halt:
|
||||||
|
cli
|
||||||
|
hlt
|
||||||
|
jmp .halt
|
||||||
|
|
||||||
|
%include "print16.asm"
|
||||||
|
|
||||||
|
name: db "Redox Loader",0
|
||||||
|
loading: db "Load ",0
|
||||||
|
errored: db "Could not read disk",0
|
||||||
|
finished: db "Finished Loading",0
|
||||||
|
line: db 13,10,0
|
||||||
|
|
||||||
|
disk: db 0
|
||||||
|
|
||||||
|
DAPACK:
|
||||||
|
db 0x10
|
||||||
|
db 0
|
||||||
|
.count: dw 0 ; int 13 resets this to # of blocks actually read/written
|
||||||
|
.buf: dw 0 ; memory buffer destination address (0:7c00)
|
||||||
|
.seg: dw 0 ; in memory page zero
|
||||||
|
.addr: dd 0 ; put the lba to read in this spot
|
||||||
|
dd 0 ; more storage bytes only for big lba's ( > 4 bytes )
|
||||||
|
|
||||||
|
times 510-($-$$) db 0
|
||||||
|
db 0x55
|
||||||
|
db 0xaa
|
||||||
46
bootloader/x86_64/descriptor_flags.inc
Normal file
46
bootloader/x86_64/descriptor_flags.inc
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
attrib:
|
||||||
|
.present equ 1 << 7
|
||||||
|
.ring1 equ 1 << 5
|
||||||
|
.ring2 equ 1 << 6
|
||||||
|
.ring3 equ 1 << 5 | 1 << 6
|
||||||
|
.user equ 1 << 4
|
||||||
|
;user
|
||||||
|
.code equ 1 << 3
|
||||||
|
; code
|
||||||
|
.conforming equ 1 << 2
|
||||||
|
.readable equ 1 << 1
|
||||||
|
; data
|
||||||
|
.expand_down equ 1 << 2
|
||||||
|
.writable equ 1 << 1
|
||||||
|
.accessed equ 1 << 0
|
||||||
|
;system
|
||||||
|
; legacy
|
||||||
|
.tssAvailabe16 equ 0x1
|
||||||
|
.ldt equ 0x2
|
||||||
|
.tssBusy16 equ 0x3
|
||||||
|
.call16 equ 0x4
|
||||||
|
.task equ 0x5
|
||||||
|
.interrupt16 equ 0x6
|
||||||
|
.trap16 equ 0x7
|
||||||
|
.tssAvailabe32 equ 0x9
|
||||||
|
.tssBusy32 equ 0xB
|
||||||
|
.call32 equ 0xC
|
||||||
|
.interrupt32 equ 0xE
|
||||||
|
.trap32 equ 0xF
|
||||||
|
; long mode
|
||||||
|
.ldt32 equ 0x2
|
||||||
|
.tssAvailabe64 equ 0x9
|
||||||
|
.tssBusy64 equ 0xB
|
||||||
|
.call64 equ 0xC
|
||||||
|
.interrupt64 equ 0xE
|
||||||
|
.trap64 equ 0xF
|
||||||
|
|
||||||
|
flags:
|
||||||
|
.granularity equ 1 << 7
|
||||||
|
.available equ 1 << 4
|
||||||
|
;user
|
||||||
|
.default_operand_size equ 1 << 6
|
||||||
|
; code
|
||||||
|
.long_mode equ 1 << 5
|
||||||
|
; data
|
||||||
|
.reserved equ 1 << 5
|
||||||
8
bootloader/x86_64/gdt_entry.inc
Normal file
8
bootloader/x86_64/gdt_entry.inc
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
struc GDTEntry
|
||||||
|
.limitl resw 1
|
||||||
|
.basel resw 1
|
||||||
|
.basem resb 1
|
||||||
|
.attribute resb 1
|
||||||
|
.flags__limith resb 1
|
||||||
|
.baseh resb 1
|
||||||
|
endstruc
|
||||||
19
bootloader/x86_64/harddrive.asm
Normal file
19
bootloader/x86_64/harddrive.asm
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
%include "bootsector.asm"
|
||||||
|
|
||||||
|
startup_start:
|
||||||
|
%ifdef ARCH_i386
|
||||||
|
%include "startup-i386.asm"
|
||||||
|
%endif
|
||||||
|
|
||||||
|
%ifdef ARCH_x86_64
|
||||||
|
%include "startup-x86_64.asm"
|
||||||
|
%endif
|
||||||
|
align 512, db 0
|
||||||
|
startup_end:
|
||||||
|
|
||||||
|
kernel_file:
|
||||||
|
incbin "kernel.bin"
|
||||||
|
align 512, db 0
|
||||||
|
.end:
|
||||||
|
.length equ kernel_file.end - kernel_file
|
||||||
|
.length_sectors equ .length / 512
|
||||||
78
bootloader/x86_64/initialize.asm
Normal file
78
bootloader/x86_64/initialize.asm
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
SECTION .text
|
||||||
|
USE16
|
||||||
|
|
||||||
|
initialize:
|
||||||
|
.fpu: ;enable fpu
|
||||||
|
mov eax, cr0
|
||||||
|
and al, 11110011b
|
||||||
|
or al, 00100010b
|
||||||
|
mov cr0, eax
|
||||||
|
mov eax, cr4
|
||||||
|
or eax, 0x200
|
||||||
|
mov cr4, eax
|
||||||
|
fninit
|
||||||
|
ret
|
||||||
|
|
||||||
|
.sse: ;enable sse
|
||||||
|
mov eax, cr4
|
||||||
|
or ax, 0000011000000000b
|
||||||
|
mov cr4, eax
|
||||||
|
ret
|
||||||
|
|
||||||
|
;PIT Frequency
|
||||||
|
;If using nanoseconds, to minimize drift, one should find a frequency as close to an integer nanosecond value in wavelength
|
||||||
|
;Divider Hz Nanoseconds Properties
|
||||||
|
;2685 444.38795779019242706393 2250286.00003631746492922946 Best For Context Switching
|
||||||
|
;5370 222.19397889509621353196 4500572.00007263492985856020
|
||||||
|
;21029 56.73981961418358774390 17624306.99991199998882825455
|
||||||
|
;23714 50.31549576902532962244 19874592.99994831745375667118
|
||||||
|
;26399 45.19798729749864262535 22124878.99998463491868476373
|
||||||
|
;29084 41.02536331545408701233 24375165.00002095238361424615
|
||||||
|
;31769 37.55804925136663623868 26625451.00005726984854313455
|
||||||
|
;34454 34.63115071302799868423 28875737.00009358731347639618
|
||||||
|
;50113 23.80982313305263437963 41999471.99993295237244784676
|
||||||
|
;52798 22.59899364874932131267 44249757.99996926983737931766
|
||||||
|
;55483 21.50535599492937776736 46500044.00000558730230583335 Lowest Drift
|
||||||
|
;58168 20.51268165772704350616 48750330.00004190476724037528
|
||||||
|
;60853 19.60760630809765610021 51000616.00007822223218031738
|
||||||
|
|
||||||
|
.pit:
|
||||||
|
;initialize the PIT
|
||||||
|
mov ax, 5370 ;this is the divider for the PIT
|
||||||
|
out 0x40, al
|
||||||
|
rol ax, 8
|
||||||
|
out 0x40, al
|
||||||
|
;DISABLED ;enable rtc interrupt
|
||||||
|
;mov al, 0xB
|
||||||
|
;out 0x70, al
|
||||||
|
;rol ax, 8
|
||||||
|
;in al, 0x71
|
||||||
|
;rol ax, 8
|
||||||
|
;out 0x70, al
|
||||||
|
;rol ax, 8
|
||||||
|
;or al, 0x40
|
||||||
|
;out 0x71, al
|
||||||
|
ret
|
||||||
|
|
||||||
|
.pic: ;sets up IRQs at int 20-2F
|
||||||
|
mov al, 0x11
|
||||||
|
out 0x20, al
|
||||||
|
out 0xA0, al
|
||||||
|
mov al, 0x20 ;IRQ0 vector
|
||||||
|
out 0x21, al
|
||||||
|
mov al, 0x28 ;IRQ8 vector
|
||||||
|
out 0xA1, al
|
||||||
|
mov al, 4
|
||||||
|
out 0x21, al
|
||||||
|
mov al, 2
|
||||||
|
out 0xA1, al
|
||||||
|
mov al, 1
|
||||||
|
out 0x21, al
|
||||||
|
out 0xA1, al
|
||||||
|
xor al, al ;no IRQ masks
|
||||||
|
out 0x21, al
|
||||||
|
out 0xA1, al
|
||||||
|
mov al, 0x20 ;reset PIC's
|
||||||
|
out 0xA0, al
|
||||||
|
out 0x20, al
|
||||||
|
ret
|
||||||
32
bootloader/x86_64/memory_map.asm
Normal file
32
bootloader/x86_64/memory_map.asm
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
SECTION .text
|
||||||
|
USE16
|
||||||
|
;Generate a memory map at 0x500 to 0x5000 (available memory not used for kernel or bootloader)
|
||||||
|
memory_map:
|
||||||
|
.start equ 0x0500
|
||||||
|
.end equ 0x5000
|
||||||
|
.length equ .end - .start
|
||||||
|
|
||||||
|
xor eax, eax
|
||||||
|
mov di, .start
|
||||||
|
mov ecx, .length / 4 ; moving 4 Bytes at once
|
||||||
|
cld
|
||||||
|
rep stosd
|
||||||
|
|
||||||
|
mov di, .start
|
||||||
|
mov edx, 0x534D4150
|
||||||
|
xor ebx, ebx
|
||||||
|
.lp:
|
||||||
|
mov eax, 0xE820
|
||||||
|
mov ecx, 24
|
||||||
|
|
||||||
|
int 0x15
|
||||||
|
jc .done ; Error or finished
|
||||||
|
|
||||||
|
cmp ebx, 0
|
||||||
|
je .done ; Finished
|
||||||
|
|
||||||
|
add di, 24
|
||||||
|
cmp di, .end
|
||||||
|
jb .lp ; Still have buffer space
|
||||||
|
.done:
|
||||||
|
ret
|
||||||
66
bootloader/x86_64/print16.asm
Normal file
66
bootloader/x86_64/print16.asm
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
SECTION .text
|
||||||
|
USE16
|
||||||
|
; provide function for printing in x86 real mode
|
||||||
|
|
||||||
|
|
||||||
|
; a newline
|
||||||
|
newline: db 0xD, 0xA, 0
|
||||||
|
|
||||||
|
; print a string and a newline
|
||||||
|
; IN
|
||||||
|
; si: points at zero-terminated String
|
||||||
|
; CLOBBER
|
||||||
|
; ax
|
||||||
|
print_line:
|
||||||
|
mov si, newline
|
||||||
|
call print
|
||||||
|
ret
|
||||||
|
|
||||||
|
; print a string
|
||||||
|
; IN
|
||||||
|
; si: points at zero-terminated String
|
||||||
|
; CLOBBER
|
||||||
|
; ax
|
||||||
|
print:
|
||||||
|
lodsb
|
||||||
|
test al, al
|
||||||
|
jz .done
|
||||||
|
call print_char
|
||||||
|
jmp print
|
||||||
|
.done:
|
||||||
|
ret
|
||||||
|
|
||||||
|
; print a character
|
||||||
|
; IN
|
||||||
|
; al: character to print
|
||||||
|
; CLOBBER
|
||||||
|
; ah
|
||||||
|
print_char:
|
||||||
|
mov ah, 0x0e
|
||||||
|
int 0x10
|
||||||
|
ret
|
||||||
|
|
||||||
|
; print a number in hex
|
||||||
|
; IN
|
||||||
|
; bx: the number
|
||||||
|
; CLOBBER
|
||||||
|
; cx, ax
|
||||||
|
print_num:
|
||||||
|
mov cx, 4
|
||||||
|
.lp:
|
||||||
|
mov al, bh
|
||||||
|
shr al, 4
|
||||||
|
|
||||||
|
cmp al, 0xA
|
||||||
|
jb .below_0xA
|
||||||
|
|
||||||
|
add al, 'A' - 0xA - '0'
|
||||||
|
.below_0xA:
|
||||||
|
add al, '0'
|
||||||
|
|
||||||
|
call print_char
|
||||||
|
|
||||||
|
shl bx, 4
|
||||||
|
loop .lp
|
||||||
|
|
||||||
|
ret
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue