Skip to content

Commit

Permalink
x86 "port" now compiles and runs
Browse files Browse the repository at this point in the history
  • Loading branch information
thepowersgang committed Jan 26, 2015
1 parent af7c1f3 commit 55a2dd1
Show file tree
Hide file tree
Showing 7 changed files with 205 additions and 7 deletions.
2 changes: 2 additions & 0 deletions Kernel/arch/amd64/start.S
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@ init_stack:

/* === General Data === */
.section .data
.globl mboot_sig
.globl mboot_ptr
mboot_sig: .long 0
mboot_ptr: .long 0

Expand Down
43 changes: 43 additions & 0 deletions Kernel/arch/x86/debug.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Rust BareBones OS
* - By John Hodge (Mutabah/thePowersGang)
*
* arch/x86/debug.rs
* - Debug output channel
*
* Writes debug to the standard PC serial port (0x3F8 .. 0x3FF)
*
* == LICENCE ==
* This code has been put into the public domain, there are no restrictions on
* its use, and the author takes no liability.
*/
use prelude::*;

/// Write a string to the output channel
///
/// This method is unsafe because it does port accesses without synchronisation
pub unsafe fn puts(s: &str)
{
for b in s.bytes()
{
putb(b);
}
}

/// Write a single byte to the output channel
///
/// This method is unsafe because it does port accesses without synchronisation
pub unsafe fn putb(b: u8)
{
// Wait for the serial port's fifo to not be empty
while (::arch::x86_io::inb(0x3F8+5) & 0x20) == 0
{
// Do nothing
}
// Send the byte out the serial port
::arch::x86_io::outb(0x3F8, b);

// Also send to the bochs 0xe9 hack
::arch::x86_io::outb(0xe9, b);
}

7 changes: 6 additions & 1 deletion Kernel/arch/x86/link.ld
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
ENTRY(start)
ENTRY(start_low)
OUTPUT_FORMAT(elf32-i386)

KERNEL_BASE = 0xC0000000;

SECTIONS {
. = 0x100000;
. += SIZEOF_HEADERS;

.multiboot : AT(ADDR(.multiboot)) {
*(.multiboot)
}
Expand All @@ -14,6 +17,8 @@ SECTIONS {
*(.text .text.*)
}

start_low = start - KERNEL_BASE;

/* read-only data, page aligned to allow use of the no-execute feature */
. = ALIGN(0x1000);
.rodata : AT(ADDR(.rodata) - KERNEL_BASE) {
Expand Down
28 changes: 28 additions & 0 deletions Kernel/arch/x86/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Rust BareBones OS
* - By John Hodge (Mutabah/thePowersGang)
*
* arch/x86/mod.rs
* - Top-level file for x86 architecture
*
* == LICENCE ==
* This code has been put into the public domain, there are no restrictions on
* its use, and the author takes no liability.
*/

// x86 port IO
mod x86_io;

// Debug output channel (uses serial)
pub mod debug;

#[no_mangle]
pub fn x86_prep_page_table(buf: &mut [u32; 1024])
{
for i in 0u32 .. 1024
{
buf[i as usize] = i * 0x1000 + 3;
}
}


76 changes: 71 additions & 5 deletions Kernel/arch/x86/start.S
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ MULTIBOOT_REQVIDMODE = (1<<2)
MULTIBOOT_HEADER_MAGIC = 0x1BADB002
MULTIBOOT_HEADER_FLAGS = (MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO | MULTIBOOT_REQVIDMODE)
MULTIBOOT_CHECKSUM = -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
.section .multiboot
.section .multiboot, "a"
.globl mboot
mboot:
.long MULTIBOOT_HEADER_MAGIC
Expand All @@ -36,22 +36,88 @@ mboot:
.long 32 /* Depth (32-bit preferred) */

/* === Code === */
.section .text
.section .text, "ax"
.extern x86_prep_page_table
.globl start
start:
/* Save multiboot state */
mov %eax, mboot_sig - LINKED_BASE
mov %ebx, mboot_ptr - LINKED_BASE

/* XXX: Get rust code to prepare the page table */
mov $init_stack - LINKED_BASE, %esp
push $init_pt - LINKED_BASE
call x86_prep_page_table /* no need to subtract LINKED_BASE, relative call */
add 4, %esp

/* Enable paging */
mov $init_pd - LINKED_BASE, %eax
mov %eax, %cr3
mov %cr0, %eax
or $0x80010000, %eax /* PG & WP */
mov %eax, %cr0

lgdt GDTPtr

/* Jump High and set CS */
ljmp $0x08,$start_high
.globl start_high
.extern kmain
start_high:
/* Clear identity mapping */
movl $0, init_pd+0

/* Prep segment registers */
mov $0x10, %ax
mov %ax, %ss
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs

mov $init_stack, %esp
call kmain

/* If kmain returns, loop forefer */
.l:
hlt
jmp .l

/* === Page-aligned data === */
.section .padata

init_pd:
.long init_pt - LINKED_BASE + 3
.rept 768-1
.long 0
.endr
.long init_pt - LINKED_BASE + 3
.rept 256-1
.long 0
.endr
init_pt:
/* The contents of this table is filled by the x86_prep_page_table function */
.rept 1024
.long 0
.endr

/* === Read-write data === */
.section .data
mboot_sig: .long 0
mboot_ptr: .long 0
.globl mboot_sig
.globl mboot_ptr
mboot_sig:
.long 0
mboot_ptr:
.long 0
GDTPtr:
.word GDT - GDTEnd
.long GDT
GDT:
.long 0x00000000, 0x00000000 /* 00 NULL Entry */
.long 0x0000FFFF, 0x00CF9A00 /* 08 PL0 Code */
.long 0x0000FFFF, 0x00CF9200 /* 10 PL0 Data */
.long 0x0000FFFF, 0x00CFFA00 /* 18 PL3 Code */
.long 0x0000FFFF, 0x00CFF200 /* 20 PL3 Data */
GDTEnd:


.section .bss
Expand Down
54 changes: 54 additions & 0 deletions Kernel/arch/x86/x86_io.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Rust BareBones OS
* - By John Hodge (Mutabah/thePowersGang)
*
* arch/x86/x86_io.rs
* - Support for the x86 IO bus
*
* == LICENCE ==
* This code has been put into the public domain, there are no restrictions on
* its use, and the author takes no liability.
*/

/// Write a byte to the specified port
pub unsafe fn outb(port: u16, val: u8)
{
asm!("outb %al, %dx" : : "{dx}"(port), "{al}"(val));
}

/// Read a single byte from the specified port
pub unsafe fn inb(port: u16) -> u8
{
let ret : u8;
asm!("inb %dx, %al" : "={ax}"(ret) : "{dx}"(port));
return ret;
}

/// Write a word (16-bits) to the specified port
pub unsafe fn outw(port: u16, val: u16)
{
asm!("outb %ax, %dx" : : "{dx}"(port), "{al}"(val));
}

/// Read a word (16-bits) from the specified port
pub unsafe fn inw(port: u16) -> u16
{
let ret : u16;
asm!("inb %dx, %ax" : "={ax}"(ret) : "{dx}"(port));
return ret;
}

/// Write a long/double-word (32-bits) to the specified port
pub unsafe fn outl(port: u16, val: u32)
{
asm!("outb %eax, %dx" : : "{dx}"(port), "{al}"(val));
}

/// Read a long/double-word (32-bits) from the specified port
pub unsafe fn inl(port: u16) -> u32
{
let ret : u32;
asm!("inb %dx, %eax" : "={ax}"(ret) : "{dx}"(port));
return ret;
}

2 changes: 1 addition & 1 deletion Kernel/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ extern crate core;
#[cfg(arch__amd64)] #[path="arch/amd64/mod.rs"]
mod arch;
#[cfg(arch__x86)] #[path="arch/x86/mod.rs"]
mod arch;
pub mod arch;

// Prelude
mod prelude;
Expand Down

0 comments on commit 55a2dd1

Please sign in to comment.