Skip to content

Commit

Permalink
Added e1000 examples on Qemu
Browse files Browse the repository at this point in the history
  • Loading branch information
elliott10 committed Apr 19, 2024
1 parent 91a5786 commit eb81359
Show file tree
Hide file tree
Showing 14 changed files with 887 additions and 0 deletions.
7 changes: 7 additions & 0 deletions examples/.cargo/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[build]
target = "riscv64gc-unknown-none-elf"

[target.riscv64gc-unknown-none-elf]
rustflags = [
"-C", "link-arg=-Tsrc/boot/linker64.ld",
]
2 changes: 2 additions & 0 deletions examples/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/target
Cargo.lock
18 changes: 18 additions & 0 deletions examples/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "e1000-driver-test"
version = "0.2.0"
authors = ["Luoyuan Xiao <[email protected]>"]

[dependencies]
log = "0.4"
cfg-if = "1.0"
riscv = "0.8"
buddy_system_allocator = "0.6"
# linked_list_allocator = "0.10.5"
lazy_static = { version = "1.4", features = ["spin_no_std"] }
device_tree = { git = "https://github.com/rcore-os/device_tree-rs", rev = "2f2e55fb" }
pci = { git = "https://github.com/elliott10/pci-rs.git", rev = "583a15bf" }
e1000-driver = { path = "../" }

[features]
board-fu740 = []
57 changes: 57 additions & 0 deletions examples/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
arch ?= riscv64
board ?= qemu
target := $(arch)gc-unknown-none-elf
# target := $(arch)imac-unknown-none-elf
# when using new toolchain after 2024-04, release mode get stuck
# mode := release
mode := debug
kernel := target/$(target)/$(mode)/e1000-driver-test
bin := target/$(target)/$(mode)/e1000-driver-test.bin
img := target/$(target)/$(mode)/ext4.img

sysroot := $(shell rustc --print sysroot)
objdump := $(shell find $(sysroot) -name llvm-objdump) --arch-name=$(arch)
objcopy := $(shell find $(sysroot) -name llvm-objcopy)

BUILD_ARGS += --target $(target)
ifeq ($(mode), release)
BUILD_ARGS += --release
endif
ifeq ($(board), fu740)
BUILD_ARGS += --features board-fu740
endif

.PHONY: kernel build clean qemu run

build: kernel $(bin)

kernel:
cargo build $(BUILD_ARGS)

$(bin): kernel
$(objcopy) $(kernel) --strip-all -O binary $(bin)

asm:
$(objdump) -d $(kernel) | less

sym:
$(objdump) -t $(kernel) | less

header:
$(objdump) -x $(kernel) | less

clean:
cargo clean

qemu:
qemu-system-$(arch) \
-machine virt \
-no-reboot \
-serial mon:stdio \
-display none \
-bios default \
-kernel $(kernel) \
-netdev user,id=net0 \
-device e1000,netdev=net0

run: build qemu
6 changes: 6 additions & 0 deletions examples/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[toolchain]
channel = "nightly-2024-01-31"
components = [ "rustfmt", "llvm-tools-preview" ]
targets = [ "riscv64gc-unknown-none-elf" ]
profile = "minimal"

38 changes: 38 additions & 0 deletions examples/src/boot/entry64.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
.section .text.entry
.globl _start
_start:
#OpenSBI将DTB地址保存在a1寄存器

#关中断
csrw sie, zero

#关闭mmu
csrw satp, zero

#BSS节清零
la t0, sbss
la t1, ebss
bgeu t0, t1, 2f

1:
# sd: store double word (64 bits)
sd zero, (t0)
addi t0, t0, 8
bltu t0, t1, 1b

2:
la sp, bootstacktop
call rust_main

4:
wfi
j 4b

# stack栈空间
.section .bss.stack
.align 12
.global bootstack
bootstack:
.space 1024 * 256
.global bootstacktop
bootstacktop:
14 changes: 14 additions & 0 deletions examples/src/boot/lang_items.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use core::panic::PanicInfo;

#[panic_handler]
fn panic(info: &PanicInfo) -> !{
println!("{}", info);
crate::boot::sbi::shutdown();
unreachable!()
}

#[no_mangle]
pub extern "C" fn abort() -> !{
panic!("abort!");
}

48 changes: 48 additions & 0 deletions examples/src/boot/linker64.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
OUTPUT_ARCH(riscv)
ENTRY(_start)

/* Qemu, fu740 */
BASE_ADDRESS = 0x80200000;

SECTIONS
{
/* Load the kernel at this address: "." means the current address */
. = BASE_ADDRESS;
start = .;

.text : {
stext = .;
*(.text.entry)
*(.text .text.*)
. = ALIGN(4K);
etext = .;
}

.rodata : {
srodata = .;
*(.rodata .rodata.*)
. = ALIGN(4K);
erodata = .;
}

.data : {
sdata = .;
*(.data .data.*)
edata = .;
}

.stack : {
*(.bss.stack)
. = ALIGN(4K);
}

/* .sbss 会存放为0的static变量,系统启动时需要清0 */
.bss : {
sbss = .;
*(.bss .bss.* .sbss .sbss.*)
ebss = .;
}

. = ALIGN(4K);
PROVIDE(end = .);
}
89 changes: 89 additions & 0 deletions examples/src/boot/logger.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
use core::fmt::{self, Write};
use log::*;

pub fn getchar() -> Option<u8> {
let c = super::sbi::console_getchar();
if c < 0 {
None
} else {
Some(c as u8)
}
}

pub fn putchar(ch: char) {
super::sbi::console_putchar(ch as u8 as usize);
}

pub fn puts(s: &str) {
for ch in s.chars() {
putchar(ch);
}
}

struct Stdout;

impl fmt::Write for Stdout {
fn write_str(&mut self, s: &str) -> fmt::Result {
puts(s);
Ok(())
}
}

pub fn _print(args: fmt::Arguments) {
Stdout.write_fmt(args).unwrap();
}

#[macro_export]
macro_rules! print {
($($arg:tt)*) => ({
$crate::boot::logger::_print(format_args!($($arg)*));
});
}

#[macro_export]
macro_rules! println {
() => ($crate::print!("\n"));
($($arg:tt)*) => ($crate::print!("{}\n", format_args!($($arg)*)));
}

static LOGGER: SimpleLogger = SimpleLogger;

pub fn init(level: &str) -> Result<(), SetLoggerError> {
use core::str::FromStr;

set_logger(&LOGGER)
.map(|()| set_max_level(LevelFilter::from_str(level).unwrap_or(LevelFilter::Debug)))
}

struct SimpleLogger;

impl Log for SimpleLogger {
fn enabled(&self, metadata: &Metadata) -> bool {
metadata.level() <= Level::Trace
}

fn log(&self, record: &Record) {
if self.enabled(record.metadata()) {
println!(
"\x1b[{}m {:5} - {} \x1b[0m",
level_to_color_code(record.level()),
record.level(),
record.args()
);
}
}

fn flush(&self) {}
}

// (16进制) \x1b == \033 (8进制)

fn level_to_color_code(level: Level) -> u8 {
match level {
Level::Error => 31, // Red
Level::Warn => 33, // Yellow
Level::Info => 32, // Green
Level::Debug => 36, // SkyBlue
Level::Trace => 90, // BrightBlack
}
}
32 changes: 32 additions & 0 deletions examples/src/boot/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
core::arch::global_asm!(include_str!("entry64.asm"));

extern crate buddy_system_allocator;
//extern crate linked_list_allocator;

pub mod sbi;

#[macro_use]
pub mod logger;
use log::*;

pub mod lang_items;

//use self::linked_list_allocator::LockedHeap;
//pub static HEAP_ALLOCATOR: LockedHeap = LockedHeap::empty();


use self::buddy_system_allocator::*;
#[global_allocator]
pub static HEAP_ALLOCATOR: LockedHeap = LockedHeap::new();

pub const KERNEL_HEAP_SIZE: usize = 1024 * 1024 * 4;

pub fn init_heap() {
static mut HEAP: [u8; KERNEL_HEAP_SIZE] = [0; KERNEL_HEAP_SIZE];
unsafe {
HEAP_ALLOCATOR
.lock()
.init(HEAP.as_mut_ptr() as usize, KERNEL_HEAP_SIZE);
}
info!("heap init end");
}
69 changes: 69 additions & 0 deletions examples/src/boot/sbi.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use core::arch::asm;

pub fn console_putchar(ch: usize){
sbi_call(SBI_CONSOLE_PUTCHAR, ch, 0, 0);
}

pub fn console_getchar() -> isize {
return sbi_call(SBI_CONSOLE_GETCHAR, 0, 0, 0);
}

pub fn console_putchar_u8(ch: u8){
let ret: isize;
//let arg0: char = ch as char;
let arg0: u8 = ch;
let arg1: usize = 0;
let arg2: usize = 0;
let which: usize = 1; //SBI_ECALL_CONSOLE_PUTCHAR
unsafe{
asm!("ecall",
lateout("x10") ret,
in("x10") arg0, in("x11") arg1, in("x12") arg2, in("x17") which
);
}
}

fn sbi_call(which: usize, arg0: usize, arg1: usize, arg2: usize) -> isize{
let ret: isize;
unsafe{
asm!("ecall",
lateout("x10") ret,
in("x10") arg0, in("x11") arg1, in("x12") arg2, in("x17") which
);
}
ret
}

pub fn set_timer(stime_value: u64){
#[cfg(target_pointer_width = "32")]
sbi_call(SBI_SET_TIMER, stime_value as usize, (stime_value >> 32), 0);

#[cfg(target_pointer_width = "64")]
sbi_call(SBI_SET_TIMER, stime_value as usize, 0, 0);
}
pub fn clear_ipi(){
sbi_call(SBI_CLEAR_IPI, 0, 0, 0);
}

pub fn send_ipi(sipi_value: usize){
sbi_call(SBI_SEND_IPI, sipi_value, 0, 0);
}

pub fn set_s_insn(entry: usize){
sbi_call(SBI_SET_SINSN, entry, 0, 0);
}

pub fn shutdown(){
sbi_call(SBI_SHUTDOWN, 0, 0, 0);
}

const SBI_SET_TIMER: usize = 0;
const SBI_CONSOLE_PUTCHAR: usize = 1;
const SBI_CONSOLE_GETCHAR: usize = 2;
const SBI_CLEAR_IPI: usize = 3;
const SBI_SEND_IPI: usize = 4;
const SBI_REMOTE_FENCE_I: usize = 5;
const SBI_REMOTE_SFENCE_VMA: usize = 6;
const SBI_REMOTE_SFENCE_VMA_ASID: usize = 7;
const SBI_SHUTDOWN: usize = 8;
const SBI_SET_SINSN: usize = 100;
Loading

0 comments on commit eb81359

Please sign in to comment.