#![no_std] #![no_main] #![feature(naked_functions)] use core::panic::PanicInfo; mod uart; #[naked] #[no_mangle] #[link_section = ".text.init"] unsafe extern "C" fn _start() -> ! { use core::arch::asm; asm!( // before we use the `la` pseudo-instruction for the first time, // we need to set `gp` (google linker relaxation) ".option push", ".option norelax", "la gp, _global_pointer", ".option pop", // set the stack pointer "la sp, _init_stack_top", "la sp, _init_stack_top", // clear the BSS "la t0, _bss_start", "la t1, _bss_end", "bgeu t0, t1, 2f", "1:", "sb zero, 0(t0)", "addi t0, t0, 1", "bne t0, t1, 1b", "2:", // BSS is clear! // "tail-call" to {entry} (call without saving a return address) "tail {entry}", entry = sym entry, // {entry} refers to the function [entry] below options(noreturn) // we must handle "returning" from assembly ); } extern "C" fn entry() -> ! { println!("This should not print because the console is not initialised."); unsafe { uart::init_console(0x1000_0000) }; println!("Hello, world!"); loop { let c = uart::CONSOLE.lock().as_mut().and_then(uart::Device::get); if let Some(c) = c { print!("{}", c as char); } } } #[panic_handler] fn on_panic(_info: &PanicInfo) -> ! { loop {} }