prints hello world successfully
This commit is contained in:
parent
be4a7a3e80
commit
9516a0c7d3
5 changed files with 44 additions and 13 deletions
|
@ -6,4 +6,7 @@ edition = "2021"
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
panic = "abort"
|
panic = "abort"
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
panic = "abort"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
|
@ -10,8 +10,8 @@ qemu-system-riscv64 \
|
||||||
-machine virt \
|
-machine virt \
|
||||||
-bios none \
|
-bios none \
|
||||||
-m 3G \
|
-m 3G \
|
||||||
-d trace:exec_tb \
|
|
||||||
-kernel "$KERNEL"
|
-kernel "$KERNEL"
|
||||||
|
|
||||||
|
# -d trace:exec_tb \
|
||||||
# -smp 3 \
|
# -smp 3 \
|
||||||
# -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0 \
|
# -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0 \
|
||||||
|
|
|
@ -1,3 +1,18 @@
|
||||||
|
.attribute arch, "rv64gc"
|
||||||
|
|
||||||
|
.section .text.start
|
||||||
.global _entry
|
.global _entry
|
||||||
_entry:
|
_entry:
|
||||||
|
la sp, stack0
|
||||||
|
li a0, 1024*8
|
||||||
|
csrr a1, mhartid
|
||||||
|
addi a1, a1, 1
|
||||||
|
mul a0, a0, a1
|
||||||
|
add sp, sp, a0
|
||||||
|
|
||||||
call start
|
call start
|
||||||
|
|
||||||
|
.section .data
|
||||||
|
.align 4
|
||||||
|
stack0:
|
||||||
|
.space 8192 * 8 # 8 is NCPU in param.rs
|
||||||
|
|
|
@ -6,12 +6,24 @@ SECTIONS {
|
||||||
It seems that QEMU jumps to 0x80000000 after setting up memory, so we want
|
It seems that QEMU jumps to 0x80000000 after setting up memory, so we want
|
||||||
our kernel code to begin here.
|
our kernel code to begin here.
|
||||||
|
|
||||||
TODO: Is there an authoritative source that says that this is the address?
|
How to find this: Run QEMU using -d trace:exec_tb and see where the PC goes
|
||||||
How to test this: Run QEMU using -d trace:exec_tb and see where the PC goes
|
|
||||||
*/
|
*/
|
||||||
. = 0x80000000;
|
. = 0x80000000;
|
||||||
|
|
||||||
.text : {
|
.text : {
|
||||||
*(.text)
|
*(.text.start)
|
||||||
|
*(.text .text.*)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Important: if this section was not included, the linker would put .rodata before .text
|
||||||
|
If the linker puts ANYTHING before .text, include it explicitly in the linker script AFTER
|
||||||
|
*/
|
||||||
|
.rodata : {
|
||||||
|
*(.rodata .rodata.*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.data : {
|
||||||
|
*(.data .data.*)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
19
src/main.rs
19
src/main.rs
|
@ -1,23 +1,24 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use core::panic::PanicInfo;
|
use core::{arch::global_asm, panic::PanicInfo, ptr};
|
||||||
|
|
||||||
|
global_asm!(include_str!("asm/entry.S"));
|
||||||
|
|
||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
fn panic_handler(_: &PanicInfo) -> ! {
|
fn panic_handler(_: &PanicInfo) -> ! {
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
||||||
static HELLO: &[u8] = b"Hello World!";
|
const UART0: usize = 0x10000000;
|
||||||
|
static HELLO: &[u8] = b"Hello World!\n";
|
||||||
|
|
||||||
pub extern "C" fn start() -> ! {
|
#[no_mangle]
|
||||||
let vga_buffer = 0xb8000 as *mut u8;
|
pub unsafe extern "C" fn start() -> ! {
|
||||||
|
for c in HELLO.iter() {
|
||||||
|
while ptr::read_volatile((UART0 + 5) as *const u8) & (1 << 5) == 0 {}
|
||||||
|
|
||||||
for (i, &byte) in HELLO.iter().enumerate() {
|
ptr::write_volatile((UART0 + 0) as *mut u8, *c);
|
||||||
unsafe {
|
|
||||||
*vga_buffer.offset(i as isize * 2) = byte;
|
|
||||||
*vga_buffer.offset(i as isize * 2 + 1) = 0xb;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loop {}
|
loop {}
|
||||||
|
|
Loading…
Reference in a new issue