Arm!
This commit is contained in:
		
							parent
							
								
									c2a95c96d5
								
							
						
					
					
						commit
						6715d5c534
					
				
					 29 changed files with 385 additions and 21 deletions
				
			
		|  | @ -9,6 +9,7 @@ crate-type = ["staticlib"] | |||
| 
 | ||||
| [dependencies] | ||||
| bitflags = "*" | ||||
| ransid = "*" | ||||
| spin = "*" | ||||
| 
 | ||||
| [dependencies.goblin] | ||||
|  | @ -19,6 +20,9 @@ features = ["no_mach", "no_mach32", "no_pe", "no_pe32", "no_endian_fd", "pure"] | |||
| [dev-dependencies] | ||||
| arch_test = { path = "arch/test" } | ||||
| 
 | ||||
| [target.'cfg(target_arch = "arm")'.dependencies] | ||||
| arch_arm = { path = "arch/arm" } | ||||
| 
 | ||||
| [target.'cfg(target_arch = "x86_64")'.dependencies] | ||||
| 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) | ||||
| QEMUFLAGS=-enable-kvm -cpu host | ||||
| QEMUFLAGS=-serial mon:stdio -d guest_errors | ||||
| 
 | ||||
| UNAME := $(shell uname) | ||||
| ifeq ($(UNAME),Darwin) | ||||
| 	LD=$(ARCH)-elf-ld | ||||
| 	QEMUFLAGS= | ||||
| ifeq ($(ARCH),arm) | ||||
| 	LD=$(ARCH)-none-eabi-ld | ||||
| 	QEMUFLAGS+=-cpu arm1176 -machine integratorcp | ||||
| 	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 | ||||
| 
 | ||||
| QEMUFLAGS+=-smp 4 -machine q35 | ||||
| QEMUFLAGS+=-serial mon:stdio | ||||
| QEMUFLAGS+=-d guest_errors | ||||
| #,int,pcall
 | ||||
| #-nographic
 | ||||
| #-device intel-iommu
 | ||||
| 
 | ||||
| 
 | ||||
| all: build/harddrive.bin | ||||
| all: build/kernel.bin | ||||
| 
 | ||||
| list: build/kernel.list | ||||
| 
 | ||||
|  | @ -27,9 +30,6 @@ run: bochs | |||
| bochs: build/harddrive.bin | ||||
| 	bochs -f bochs.$(ARCH) | ||||
| 
 | ||||
| qemu: build/harddrive.bin | ||||
| 	$(QEMU) $(QEMUFLAGS) -drive file=$<,format=raw,index=0,media=disk | ||||
| 
 | ||||
| FORCE: | ||||
| 
 | ||||
| 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 $@ | ||||
| 
 | ||||
| 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 | ||||
| 	objdump -C -M intel -D $< > $@ | ||||
| 
 | ||||
| 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: | ||||
| 	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 {} | ||||
| } | ||||
							
								
								
									
										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
 | ||||
							
								
								
									
										15
									
								
								kernel/console.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								kernel/console.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,15 @@ | |||
| use ransid::Console; | ||||
| use spin::{Once, Mutex, MutexGuard}; | ||||
| 
 | ||||
| /// Console
 | ||||
| static CONSOLE: Once<Mutex<Console>> = Once::new(); | ||||
| 
 | ||||
| /// Initialize console, called if needed
 | ||||
| fn init_console() -> Mutex<Console> { | ||||
|     Mutex::new(Console::new(0, 0)) | ||||
| } | ||||
| 
 | ||||
| /// Get the global console
 | ||||
| pub fn console() -> MutexGuard<'static, Console> { | ||||
|     CONSOLE.call_once(init_console).lock() | ||||
| } | ||||
|  | @ -80,6 +80,11 @@ use arch::interrupt; | |||
| #[macro_use] | ||||
| extern crate arch_test as arch; | ||||
| 
 | ||||
| /// Architecture specific items (ARM)
 | ||||
| #[cfg(all(not(test), target_arch = "arm"))] | ||||
| #[macro_use] | ||||
| extern crate arch_arm as arch; | ||||
| 
 | ||||
| /// Architecture specific items (x86_64)
 | ||||
| #[cfg(all(not(test), target_arch = "x86_64"))] | ||||
| #[macro_use] | ||||
|  | @ -92,12 +97,17 @@ extern crate collections; | |||
| #[macro_use] | ||||
| extern crate bitflags; | ||||
| extern crate goblin; | ||||
| extern crate ransid; | ||||
| extern crate spin; | ||||
| 
 | ||||
| /// Console
 | ||||
| pub mod console; | ||||
| 
 | ||||
| /// Context management
 | ||||
| pub mod context; | ||||
| 
 | ||||
| /// ELF file parsing
 | ||||
| #[cfg(all(not(test), target_arch = "x86_64"))] | ||||
| pub mod elf; | ||||
| 
 | ||||
| /// Schemes, filesystem handlers
 | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| use core::str; | ||||
| 
 | ||||
| use syscall::Result; | ||||
| use super::Scheme; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Jeremy Soller
						Jeremy Soller