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

Commit bbc2348

Browse files
authored
feat(main): Adapt to ramdisk type boot media, use CPIO format, and add test script (#5)
- Add boot media type compilation options and source code adaptation - Add ramdisk boot media type (CPIO format) - Add test suite for ramdisk boot media type (CPIO format) Signed-off-by: JensenWei007 <jensenwei007@gmail.com>
1 parent a4a6c46 commit bbc2348

File tree

8 files changed

+140
-6
lines changed

8 files changed

+140
-6
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,6 @@ arceboot.bin
2828

2929
rustsbi/
3030

31-
/.axconfig.*
31+
/.axconfig.*
32+
33+
*.cpio

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ edition = "2024"
55
authors = ["Zhihang Shao <dio_ro@outlook.com>", "Jingxuan Wei <jensenwei007@gmail.com>"]
66

77
[features]
8-
default = ["alloc", "fs", "paging", "disk"]
8+
default = ["alloc", "fs", "paging", "ramdisk_cpio"]
99

1010
alloc = ["axalloc"]
1111
paging = ["axhal/paging", "axmm"]
@@ -14,7 +14,10 @@ fs = ["axdriver", "axfs"]
1414
net = ["axdriver", "axnet"]
1515
display = ["axdriver", "axdisplay"]
1616

17-
disk = ["axdriver/virtio-blk"]
17+
# Boot Media
18+
19+
virtiodisk = ["axdriver/virtio-blk"]
20+
ramdisk_cpio = []
1821

1922
[dependencies]
2023
axhal = { git = "https://github.com/arceos-org/arceos.git" }
@@ -29,5 +32,6 @@ axdisplay = { git = "https://github.com/arceos-org/arceos.git", optional = true
2932

3033
crate_interface = "0.1"
3134
ctor_bare = "0.2"
35+
cfg-if = "1.0"
3236

3337
chrono = { version = "0.4.38", default-features = false }

Makefile

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
# - `PLATFORM`: Target platform in the `platforms` directory
55
# - `SMP`: Number of CPUs
66
# - `LOG:` Logging level: warn, error, info, debug, trace
7+
# - `MEDIA:` Boot Media Type: ramdisk-cpio, virtio-blk
78
# - `EXTRA_CONFIG`: Extra config specification file
89
# - `OUT_CONFIG`: Final config file that takes effect
910
# * QEMU options:
@@ -14,14 +15,16 @@
1415
ARCH ?= riscv64
1516
PLATFORM ?=
1617
SMP ?= 1
17-
LOG ?= info
18+
LOG ?= debug
19+
MEDIA ?= ramdisk-cpio
1820

1921
OUT_CONFIG ?= $(PWD)/.axconfig.toml
2022
EXTRA_CONFIG ?=
2123

2224
# QEMU options
2325
DISK:= fat32_disk_test.img
2426
SBI:=rustsbi/target/riscv64imac-unknown-none-elf/release/rustsbi-prototyper-payload.elf
27+
RAMDISK_CPIO:=ramdisk.cpio
2528

2629
export AX_CONFIG_PATH=$(OUT_CONFIG)
2730
export AX_LOG=$(LOG)
@@ -44,5 +47,8 @@ clean:
4447

4548
build: clean defconfig all
4649

50+
ramdiskcpio:
51+
qemu-system-riscv64 -m 128M -serial mon:stdio -bios $(SBI) -nographic -machine virt -device loader,file=$(RAMDISK_CPIO),addr=0x84000000
52+
4753
run:
48-
qemu-system-riscv64 -serial mon:stdio -bios $(SBI) -nographic -machine virt -device virtio-blk-pci,drive=disk0 -drive id=disk0,if=none,format=raw,file=$(DISK)
54+
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)

scripts/test/ramdisk_cpio.sh

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/bin/bash
2+
set -e
3+
4+
print_info() {
5+
printf "\033[1;37m%s\033[0m" "[RustSBI-Arceboot Build For Test] "
6+
printf "\033[1;32m%s\033[0m" "[INFO] "
7+
printf "\033[36m%s\033[0m\n" "$1"
8+
}
9+
10+
print_info "开始执行 ramdisk 类型的 cpio 打包脚本"
11+
print_info "此为空镜像, 只含有一个 arceboot.txt 文件, 用于测试 Arceboot"
12+
print_info "即将在当前目录执行创建 -------->"
13+
14+
mkdir myramdisk
15+
touch myramdisk/arceboot.txt
16+
echo "This is a test file for Arceboot." > myramdisk/arceboot.txt
17+
18+
cd myramdisk
19+
find . | cpio -o --format=newc > ../ramdisk.cpio
20+
cd ..
21+
22+
rm -rf myramdisk
23+
24+
print_info "创建完成, 生成的 ramdisk.cpio 位于当前目录"

src/main.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ extern crate axlog;
66

77
mod panic;
88
mod log;
9+
mod media;
910

1011
#[cfg_attr(not(test), unsafe(no_mangle))]
1112
pub extern "C" fn rust_main(_cpu_id: usize, _dtb: usize) -> ! {
@@ -39,7 +40,9 @@ pub extern "C" fn rust_main(_cpu_id: usize, _dtb: usize) -> ! {
3940
let all_devices = axdriver::init_drivers();
4041

4142
#[cfg(feature = "fs")]
42-
axfs::init_filesystems(all_devices.block);
43+
// 目前使用ramdisk的cpio格式时,驱动还不完善,用不了,需要注释掉
44+
// 如果使用virtio-blk驱动,则可以正常使用
45+
//axfs::init_filesystems(all_devices.block);
4346

4447
#[cfg(feature = "net")]
4548
axnet::init_network(all_devices.net);
@@ -49,6 +52,10 @@ pub extern "C" fn rust_main(_cpu_id: usize, _dtb: usize) -> ! {
4952
}
5053
ctor_bare::call_ctors();
5154

55+
info!("will test cpio.");
56+
57+
crate::media::parse_cpio_ramdisk();
58+
5259
info!("will shut down.");
5360

5461
axhal::misc::terminate();

src/media/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
cfg_if::cfg_if! {
2+
if #[cfg(feature = "ramdisk_cpio")] {
3+
mod ramdisk_cpio;
4+
pub use ramdisk_cpio::*;
5+
} else {
6+
info!("Boot media feature is not enabled.");
7+
}
8+
}

src/media/ramdisk_cpio.rs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
use core::{ptr, str};
2+
use axhal::mem::phys_to_virt;
3+
4+
const CPIO_MAGIC: &[u8; 6] = b"070701";
5+
const CPIO_BASE: usize = 0x8400_0000;
6+
7+
#[repr(C)]
8+
#[derive(Debug)]
9+
struct CpioNewcHeader {
10+
c_magic: [u8; 6],
11+
c_ino: [u8; 8],
12+
c_mode: [u8; 8],
13+
c_uid: [u8; 8],
14+
c_gid: [u8; 8],
15+
c_nlink: [u8; 8],
16+
c_mtime: [u8; 8],
17+
c_filesize: [u8; 8],
18+
c_devmajor: [u8; 8],
19+
c_devminor: [u8; 8],
20+
c_rdevmajor: [u8; 8],
21+
c_rdevminor: [u8; 8],
22+
c_namesize: [u8; 8],
23+
c_check: [u8; 8],
24+
}
25+
26+
fn parse_hex_field(field: &[u8]) -> usize {
27+
// 将ASCII十六进制转换为数字
28+
let s = core::str::from_utf8(field).unwrap_or("0");
29+
usize::from_str_radix(s, 16).unwrap_or(0)
30+
}
31+
32+
pub fn parse_cpio_ramdisk() {
33+
let mut ptr = phys_to_virt(CPIO_BASE.into()).as_usize();
34+
35+
loop {
36+
let hdr = unsafe { &*(ptr as *const CpioNewcHeader) };
37+
38+
if &hdr.c_magic != CPIO_MAGIC {
39+
info!("Invalid magic at {:#x}", ptr);
40+
break;
41+
}
42+
43+
let namesize = parse_hex_field(&hdr.c_namesize);
44+
let filesize = parse_hex_field(&hdr.c_filesize);
45+
46+
// 文件名在 header 后面紧跟着
47+
let name_ptr = ptr + core::mem::size_of::<CpioNewcHeader>();
48+
let name = unsafe {
49+
let slice = core::slice::from_raw_parts(name_ptr as *const u8, namesize - 1); // 去掉末尾的 '\0'
50+
str::from_utf8(slice).unwrap_or("<invalid utf8>")
51+
};
52+
53+
if name == "TRAILER!!!" {
54+
info!("End of CPIO archive.");
55+
break;
56+
}
57+
58+
info!("Found file: {}, size: {}", name, filesize);
59+
60+
// 文件数据
61+
let file_start = align_up(name_ptr + namesize, 4);
62+
let file_end = file_start + filesize;
63+
64+
if name == "arceboot.txt" {
65+
let data = unsafe {
66+
core::slice::from_raw_parts(file_start as *const u8, filesize)
67+
};
68+
if let Ok(text) = core::str::from_utf8(data) {
69+
info!("Content of {}:\n{}", name, text);
70+
} else {
71+
info!("Binary content of {}: {:02x?}", name, &data[0..core::cmp::min(32, data.len())]);
72+
}
73+
}
74+
75+
// 移动到下一个 header
76+
ptr = align_up(file_end, 4);
77+
}
78+
}
79+
80+
fn align_up(addr: usize, align: usize) -> usize {
81+
(addr + align - 1) & !(align - 1)
82+
}

0 commit comments

Comments
 (0)