Skip to content
This repository was archived by the owner on Feb 7, 2026. It is now read-only.

Commit 3bf2325

Browse files
committed
feat(main): Adapt command line and autoboot, optimize Makefile
- Add command line module to implement module framework for subsequent expansion. - Change the boot process, enable autoboot by default, automatically search for bootable devices and start them, and you can also interrupt and enter the command line to operate on your own - Optimize the makefile content. Signed-off-by: JensenWei007 <jensenwei007@gmail.com>
1 parent 88344a0 commit 3bf2325

8 files changed

Lines changed: 325 additions & 18 deletions

File tree

.github/workflows/test.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ jobs:
6464
sudo apt install -y qemu-system-misc
6565
6666
- name: Run QEMU
67-
run: make virtiodisk > qemu.log
67+
run: |
68+
make qemu-run > qemu.log
6869
6970
- name: Upload QEMU log
7071
uses: actions/upload-artifact@v4

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,6 @@ myramdisk/
3232
*.bin
3333
*.img
3434
*.cpio
35+
36+
edk2/
37+
mnt_fat32/

Makefile

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
# - `PLATFORM`: Target platform in the `platforms` directory
55
# - `SMP`: Number of CPUs
66
# - `LOG:` Logging level: warn, error, info, debug, trace
7-
# - `MEDIUM:` Boot Medium Type: ramdisk-cpio, virtio-blk
87
# - `EXTRA_CONFIG`: Extra config specification file
98
# - `OUT_CONFIG`: Final config file that takes effect
109
# * QEMU options:
@@ -17,15 +16,12 @@ PLATFORM ?=
1716
SMP ?= 1
1817
LOG ?= debug
1918

20-
# 下面的目前还没用, 现在需要手动去cargo.toml中修改, 后面补上
21-
MEDIUM ?= ramdisk-cpio
22-
2319
OUT_CONFIG ?= $(PWD)/.axconfig.toml
2420
EXTRA_CONFIG ?=
2521

2622
# QEMU options
2723
DISK:= disk.img
28-
SBI:=rustsbi/target/riscv64imac-unknown-none-elf/release/rustsbi-prototyper-payload.elf
24+
SBI ?= rustsbi/target/riscv64gc-unknown-none-elf/release/rustsbi-prototyper-payload.elf
2925
RAMDISK_CPIO:=ramdisk.cpio
3026

3127
export AX_CONFIG_PATH=$(OUT_CONFIG)
@@ -44,13 +40,10 @@ oldconfig: _axconfig-gen
4440

4541
clean:
4642
cargo clean
47-
cd rustsbi && cargo clean
43+
test -d "rustsbi" && cd rustsbi && cargo clean
4844
rm -f $(OUT_CONFIG)
4945

5046
build: clean defconfig all
5147

52-
ramdiskcpio:
53-
qemu-system-riscv64 -m 128M -serial mon:stdio -bios $(SBI) -nographic -machine virt -device loader,file=$(RAMDISK_CPIO),addr=0x84000000
54-
55-
virtiodisk:
56-
qemu-system-riscv64 -m 128M -serial mon:stdio -bios $(SBI) -nographic -machine virt -device virtio-blk-pci,drive=disk0 -drive id=disk0,if=none,format=raw,file=$(DISK)
48+
qemu-run:
49+
qemu-system-riscv64 -m 128M -serial mon:stdio -bios $(SBI) -nographic -machine virt -nographic -machine virt -device virtio-blk-pci,drive=disk0 -drive id=disk0,if=none,format=raw,file=$(DISK)

scripts/make/build.mk

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ ROOT_DIR := $(abspath $(SCRIPT_DIR)/../..)
77
ELF := $(ROOT_DIR)/target/$(TARGET)/release/arceboot
88
BIN := $(ROOT_DIR)/target/$(TARGET)/release/arceboot.bin
99
RUSTSBI_DIR := $(ROOT_DIR)/rustsbi
10-
SBI := $(RUSTSBI_DIR)/target/riscv64imac-unknown-none-elf/release/rustsbi-prototyper-payload.elf
1110

1211
# 彩色打印
1312
define print_info

src/main.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ mod log;
99
mod medium;
1010
mod panic;
1111
mod runtime;
12+
mod shell;
1213

1314
#[cfg_attr(not(test), unsafe(no_mangle))]
1415
pub extern "C" fn rust_main(_cpu_id: usize, _dtb: usize) -> ! {
@@ -36,7 +37,7 @@ pub extern "C" fn rust_main(_cpu_id: usize, _dtb: usize) -> ! {
3637
info!("Initialize platform devices...");
3738
axhal::platform_init();
3839

39-
#[cfg(any(feature = "fs", feature = "net", feature = "display"))]
40+
#[cfg(any(feature = "fs", feature = "net"))]
4041
{
4142
#[allow(unused_variables)]
4243
let all_devices = axdriver::init_drivers();
@@ -48,16 +49,13 @@ pub extern "C" fn rust_main(_cpu_id: usize, _dtb: usize) -> ! {
4849

4950
#[cfg(feature = "net")]
5051
axnet::init_network(all_devices.net);
51-
52-
#[cfg(feature = "display")]
53-
axdisplay::init_display(all_devices.display);
5452
}
5553
ctor_bare::call_ctors();
5654

5755
info!("current root dir: {}", crate::medium::current_dir().unwrap());
5856
info!("read test file context: {}", crate::medium::read_to_string("/test/arceboot.txt").unwrap());
5957

60-
crate::runtime::efi_runtime_init();
58+
crate::shell::shell_main();
6159

6260
info!("will shut down.");
6361

src/shell/cmd.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
type CmdHandler = fn(&str);
2+
3+
const CMD_TABLE: &[(&str, &str, CmdHandler)] = &[
4+
("help", "-- List the help for ArceBoot", do_help),
5+
("exit", "-- Exit ArceBoot", do_exit),
6+
];
7+
8+
pub fn run_cmd(line: &[u8]) {
9+
let line_str = unsafe { core::str::from_utf8_unchecked(line) };
10+
let (cmd, args) = split_whitespace(line_str);
11+
if !cmd.is_empty() {
12+
for (name, _, func) in CMD_TABLE {
13+
if cmd == *name {
14+
func(args);
15+
return;
16+
}
17+
}
18+
axlog::ax_println!("{}: command not found", cmd);
19+
}
20+
}
21+
22+
fn split_whitespace(str: &str) -> (&str, &str) {
23+
let str = str.trim();
24+
str.find(char::is_whitespace)
25+
.map_or((str, ""), |n| (&str[..n], str[n + 1..].trim()))
26+
}
27+
28+
fn do_help(_args: &str) {
29+
axlog::ax_println!("Available commands:");
30+
for (name, desc, _) in CMD_TABLE {
31+
axlog::ax_print!(" {}", name);
32+
axlog::ax_println!(" {}", desc);
33+
}
34+
}
35+
36+
fn do_exit(_args: &str) {
37+
axlog::ax_println!("======== ArceBoot will exit and shut down ========");
38+
axhal::misc::terminate();
39+
}

src/shell/mod.rs

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
use axio::{Read, Write};
2+
3+
mod cmd;
4+
mod stdio;
5+
6+
const LF: u8 = b'\n';
7+
const CR: u8 = b'\r';
8+
const DL: u8 = b'\x7f';
9+
const BS: u8 = b'\x08';
10+
const SPACE: u8 = b' ';
11+
12+
const MAX_CMD_LEN: usize = 256;
13+
14+
fn print_prompt() {
15+
axlog::ax_print!("[Arceboot]: {}$ ", &crate::medium::current_dir().unwrap());
16+
}
17+
18+
pub fn shell_main() {
19+
let mut stdin = self::stdio::stdin();
20+
let mut stdout = self::stdio::stdout();
21+
22+
let mut buf = [0; MAX_CMD_LEN];
23+
let mut cursor = 0;
24+
25+
// Attempt to autoboot
26+
const COUNTDOWN_MSG: &[u8] =
27+
b"[Arceboot] Attempt to autoboot, print any key to stop it, will start autoboot in: ";
28+
for i in (0..=5).rev() {
29+
if stdin.read_nb(&mut buf[cursor..cursor + 1]).ok() == Some(1) {
30+
break;
31+
}
32+
stdout.write_all(COUNTDOWN_MSG).unwrap();
33+
34+
let num_char = b'0' + i;
35+
stdout.write_all(&[num_char, b' ']).unwrap();
36+
37+
axhal::time::busy_wait(core::time::Duration::new(1, 0));
38+
39+
if i > 0 {
40+
stdout.write_all(&[CR]).unwrap();
41+
}
42+
43+
if i == 0 {
44+
autoboot();
45+
// boot 完成后理论上不应该回到程序
46+
return;
47+
}
48+
}
49+
axlog::ax_println!();
50+
51+
// Cannot autoboot or cancel autoboot
52+
self::cmd::run_cmd("help".as_bytes());
53+
print_prompt();
54+
55+
loop {
56+
if stdin.read(&mut buf[cursor..cursor + 1]).ok() != Some(1) {
57+
continue;
58+
}
59+
if buf[cursor] == b'\x1b' {
60+
buf[cursor] = b'^';
61+
}
62+
match buf[cursor] {
63+
CR | LF => {
64+
axlog::ax_println!();
65+
if cursor > 0 {
66+
cmd::run_cmd(&buf[..cursor]);
67+
cursor = 0;
68+
}
69+
print_prompt();
70+
}
71+
BS | DL => {
72+
if cursor > 0 {
73+
stdout.write_all(&[BS, SPACE, BS]).unwrap();
74+
cursor -= 1;
75+
}
76+
}
77+
0..=31 => {}
78+
c => {
79+
if cursor < MAX_CMD_LEN - 1 {
80+
stdout.write_all(&[c]).unwrap();
81+
cursor += 1;
82+
}
83+
}
84+
}
85+
}
86+
}
87+
88+
fn autoboot() {
89+
crate::runtime::efi_runtime_init();
90+
}

0 commit comments

Comments
 (0)