merge upstream

This commit is contained in:
luchangcheng2333 2022-05-10 21:14:52 +08:00
commit d2acb4386e
16 changed files with 705 additions and 498 deletions

View File

@ -17,7 +17,6 @@ jobs:
toolchain: nightly-2022-01-20
override: true
components: rust-src, rustfmt, clippy
- uses: Swatinem/rust-cache@v1
- name: Check format
uses: actions-rs/cargo@v1
@ -50,7 +49,6 @@ jobs:
toolchain: nightly-2022-01-20
override: true
target: aarch64-unknown-linux-gnu
- uses: Swatinem/rust-cache@v1
- uses: actions-rs/cargo@v1
with:
command: build
@ -65,8 +63,8 @@ jobs:
os: [ubuntu-20.04, macos-latest]
steps:
- uses: actions/checkout@v3
with:
lfs: true
- name: Pull prebuilt images
run: git lfs pull -I prebuilt/zircon/x64/libc.so,prebuilt/zircon/x64/libfdio.so,prebuilt/zircon/x64/libunwind.so,prebuilt/zircon/x64/libzircon.so,prebuilt/zircon/x64/Scrt1.o
- uses: actions-rs/toolchain@v1
with:
profile: minimal

View File

@ -11,14 +11,14 @@ jobs:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
with:
lfs: true
- name: Pull prebuilt images
run: git lfs pull -I prebuilt/linux/libc-libos.so,prebuilt/zircon/x64/bringup.zbi,prebuilt/zircon/x64/libzircon-libos.so,prebuilt/zircon/x64/userboot-libos.so
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: nightly-2022-01-20
components: rust-src, llvm-tools-preview, rustfmt, clippy
- uses: Swatinem/rust-cache@v1
# - uses: Swatinem/rust-cache@v1
- name: Prepare rootfs
run: make rootfs
@ -52,7 +52,7 @@ jobs:
profile: minimal
toolchain: nightly-2022-01-20
components: rust-src, llvm-tools-preview, rustfmt, clippy
- uses: Swatinem/rust-cache@v1
# - uses: Swatinem/rust-cache@v1
- uses: actions-rs/cargo@v1
with:
@ -63,14 +63,15 @@ jobs:
steps:
- uses: actions/checkout@v3
with:
lfs: true
submodules: 'recursive'
- name: Pull prebuilt images
run: git lfs pull -I prebuilt/zircon/x64/core-tests.zbi,prebuilt/zircon/x64/libzircon-libos.so,prebuilt/zircon/x64/userboot-libos.so
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: nightly-2022-01-20
components: rust-src, llvm-tools-preview, rustfmt, clippy
- uses: Swatinem/rust-cache@v1
# - uses: Swatinem/rust-cache@v1
- name: Install dependencies
run: pip3 install -r tests/requirements.txt
@ -86,14 +87,15 @@ jobs:
steps:
- uses: actions/checkout@v3
with:
lfs: true
submodules: 'recursive'
- name: Pull prebuilt images
run: git lfs pull -I prebuilt/linux/libc-libos.so
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: nightly-2022-01-20
components: rust-src, llvm-tools-preview, rustfmt, clippy
- uses: Swatinem/rust-cache@v1
# - uses: Swatinem/rust-cache@v1
- name: Install dependencies
run: |
@ -101,7 +103,7 @@ jobs:
sudo apt-get install musl-tools musl-dev -y
pip3 install -r tests/requirements.txt
- name: Prepare rootfs
run: make rootfs && make libc-test
run: make libc-test
- name: Run fast tests
if: github.event_name != 'schedule'
run: cd tests && python3 linux_libc_test.py --libos --fast
@ -118,14 +120,15 @@ jobs:
steps:
- uses: actions/checkout@v3
with:
lfs: true
submodules: 'recursive'
- name: Pull prebuilt images
run: git lfs pull -I prebuilt/zircon/x64/core-tests.zbi,prebuilt/zircon/x64/libzircon.so,prebuilt/zircon/x64/userboot.so
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: nightly-2022-01-20
components: rust-src, llvm-tools-preview, rustfmt, clippy
- uses: Swatinem/rust-cache@v1
# - uses: Swatinem/rust-cache@v1
- name: Install dependencies
run: |
@ -167,8 +170,9 @@ jobs:
steps:
- uses: actions/checkout@v3
with:
lfs: true
submodules: 'recursive'
- name: Pull prebuilt images
run: git lfs pull -I prebuilt/linux/libc-libos.so
- uses: actions-rs/toolchain@v1
with:
profile: minimal
@ -179,7 +183,7 @@ jobs:
with:
crate: cargo-binutils
version: latest
- uses: Swatinem/rust-cache@v1
# - uses: Swatinem/rust-cache@v1
- name: Install dependencies
run: |
@ -223,8 +227,9 @@ jobs:
steps:
- uses: actions/checkout@v3
with:
lfs: true
submodules: 'recursive'
- name: Pull prebuilt images
run: git lfs pull -I prebuilt/linux/libc-libos.so
- uses: actions-rs/toolchain@v1
with:
profile: minimal
@ -235,7 +240,7 @@ jobs:
with:
crate: cargo-binutils
version: latest
- uses: Swatinem/rust-cache@v1
# - uses: Swatinem/rust-cache@v1
- name: Install dependencies
run: |

4
.gitignore vendored
View File

@ -6,10 +6,10 @@
**/target
**/*.rs.bk
*.img
*.bin
*.log
Cargo.lock
/toolchain
/ignored
/rootfs
/riscv_rootfs
@ -18,8 +18,8 @@ Cargo.lock
/prebuilt/linux/**/minirootfs.tar.*
/prebuilt/linux/riscv64/prebuild*
/prebuilt/linux/aarch64/*
zCore/src/platform/riscv/boot/kernel-vars.ld
zCore/disk/*
zCore/src/platform/riscv/boot/kernel-vars.ld
.idea
.DS_Store
__pycache__

View File

@ -1,81 +1,41 @@
# Makefile for top level of zCore
# Possible things to $(MAKE):
#
# rootfs-x64 : contains alpine-rootfs for x86_64, and compiled binary of linux-syscall/test/*.c
# riscv-rootfs : prebuilt binary for riscv64, contains busybox, libc-test and oscomp
# aarch64-rootfs: prebuilt binary for aarch64
# libc-test : build binary of libc-test for x86_64
# rcore-fs-fuse : install a tool called rcore-fs-fuse
# image : make a normal x86_64 image from alpine-rootfs
# riscv-image : make a riscv64 image from riscv-rootfs for testing
# aarch64-image: make a aarch6464 image from aarch64-rootfs for testing
# clean : delete all files generated by compilation
# doc : cargo doc --open
# baremetal-test-img : make a x86_64 image for testing
ROOTFS_TAR := alpine-minirootfs-3.12.0-x86_64.tar.gz
ROOTFS_URL := http://dl-cdn.alpinelinux.org/alpine/v3.12/releases/x86_64/$(ROOTFS_TAR)
RISCV64_ROOTFS_TAR := prebuild.tar.xz
RISCV64_ROOTFS_URL := https://github.com/rcore-os/libc-test-prebuilt/releases/download/0.1/$(RISCV64_ROOTFS_TAR)
LIBC_TEST_URL := https://github.com/rcore-os/libc-test.git
AARCH64_ROOTFS_TAR := alpine-minirootfs-3.15.4-aarch64.tar.gz
AARCH64_ROOTFS_URL := http://dl-cdn.alpinelinux.org/alpine/v3.15/releases/aarch64/$(AARCH64_ROOTFS_TAR)
CROSS_TOOLCHAIN := http://musl.cc/riscv64-linux-musl-cross.tgz
PATH := $(PATH):$(PWD)/toolchain/riscv64-linux-musl-cross/bin
ARCH ?= x86_64
.PHONY: rootfs libc-test image test-image check doc clean
.PHONY: help setup rootfs libc-test image test-image check doc clean
# print top level help
help:
cargo xtask help
# setup git lfs and git submodules
setup:
cargo setup
# update toolchain and dependencies
update:
cargo update-all
# put rootfs for linux mode
rootfs:
cargo rootfs $(ARCH)
.PHONY: rootfs libc-test rcore-fs-fuse image
prebuilt/linux/$(ROOTFS_TAR):
wget $(ROOTFS_URL) -O $@
prebuilt/linux/riscv64/$(RISCV64_ROOTFS_TAR):
@wget $(RISCV64_ROOTFS_URL) -O $@
prebuilt/linux/aarch64/$(AARCH64_ROOTFS_TAR):
@wget $(AARCH64_ROOTFS_URL) -O $@
toolchain:
@mkdir -p toolchain
@cd toolchain && wget $(CROSS_TOOLCHAIN)
@cd toolchain && tar xzf riscv64-linux-musl-cross.tgz
rootfs: prebuilt/linux/$(ROOTFS_TAR)
rm -rf rootfs && mkdir -p rootfs
tar xf $< -C rootfs
# libc-libos.so (convert syscall to function call) is from https://github.com/rcore-os/musl/tree/rcore
cp prebuilt/linux/libc-libos.so rootfs/lib/ld-musl-x86_64.so.1
@for VAR in $(BASENAMES); do gcc $(TEST_DIR)$$VAR.c -o $(DEST_DIR)$$VAR $(CFLAG); done
riscv-rootfs:prebuilt/linux/riscv64/$(RISCV64_ROOTFS_TAR)
@rm -rf riscv_rootfs && mkdir -p riscv_rootfs
@tar -xvf $< -C riscv_rootfs --strip-components 1
@ln -s busybox riscv_rootfs/bin/ls
aarch64-rootfs: prebuilt/linux/aarch64/$(AARCH64_ROOTFS_TAR)
@rm -rf aarch64_rootfs && mkdir -p aarch64_rootfs
@tar -xvf $< -C aarch64_rootfs --strip-components 1
# put libc-test into rootfs
libc-test:
cargo libc-test $(ARCH)
image: rootfs
# build image from rootfs
image:
cargo image $(ARCH)
test-image: rootfs libc-test image
# build image with libc-test
test-image: libc-test image
# check code style
check:
cargo xtask check
cargo check-style
# build and open project document
doc:
cargo doc --open

View File

@ -6,6 +6,10 @@
Reimplement [Zircon][zircon] microkernel in safe Rust as a userspace program!
## Manual
[This](docs/Manual.md) is a new simple chinese manual.
## Dev Status
🚧 Working In Progress
@ -24,9 +28,9 @@ make run ARCH=riscv64 LINUX=1
Environments
* [Rust toolchain](http://rustup.rs)
* [QEMU](https://www.qemu.org)
* [Git LFS](https://git-lfs.github.com)
- [Rust toolchain](http://rustup.rs)
- [QEMU](https://www.qemu.org)
- [Git LFS](https://git-lfs.github.com)
### Developing environment info
@ -48,15 +52,18 @@ For users in China, there's a mirror you can try:
```sh
git clone https://github.com.cnpmjs.org/rcore-os/zCore --recursive
```
### Run zcore in libos mode
#### Run zcore in linux-libos mode
* step 1: Prepare Alpine Linux rootfs:
- step 1: Prepare Alpine Linux rootfs:
```sh
make rootfs
```
* step 2: Compile & Run native Linux program (Busybox) in libos mode:
- step 2: Compile & Run native Linux program (Busybox) in libos mode:
```sh
cargo run --release --features "linux libos" -- /bin/busybox [args]
@ -68,7 +75,7 @@ git clone https://github.com.cnpmjs.org/rcore-os/zCore --recursive
#### Run native Zircon program (shell) in zircon-libos mode:
* step 1: Compile and Run Zircon shell
- step 1: Compile and Run Zircon shell
```sh
cargo run --release --features "zircon libos" -- prebuilt/zircon/x64/bringup.zbi
@ -77,15 +84,16 @@ git clone https://github.com.cnpmjs.org/rcore-os/zCore --recursive
The `graphic` and `LOG` options are the same as Linux.
### Run zcore in bare-metal mode
#### Run Linux shell in linux-bare-metal mode:
* step 1: Prepare Alpine Linux rootfs:
- step 1: Prepare Alpine Linux rootfs:
```sh
make rootfs
```
* step 2: Create Linux rootfs image:
- step 2: Create Linux rootfs image:
Note: Before below step, you can add some special apps in zCore/rootfs
@ -93,7 +101,7 @@ git clone https://github.com.cnpmjs.org/rcore-os/zCore --recursive
make image
```
* step 3: Build and run zcore in linux-bare-metal mode:
- step 3: Build and run zcore in linux-bare-metal mode:
```sh
cd zCore && make run MODE=release LINUX=1 [LOG=warn] [GRAPHIC=on] [ACCEL=1]
@ -101,13 +109,13 @@ git clone https://github.com.cnpmjs.org/rcore-os/zCore --recursive
#### Run Zircon shell in zircon-bare-metal mode:
* step 1: Build and run zcore in zircon-bare-metal mode:
- step 1: Build and run zcore in zircon-bare-metal mode:
```sh
cd zCore && make run MODE=release [LOG=warn] [GRAPHIC=on] [ACCEL=1]
```
* step 2: Build and run your own Zircon user programs:
- step 2: Build and run your own Zircon user programs:
```sh
# See template in zircon-user
@ -118,6 +126,7 @@ git clone https://github.com.cnpmjs.org/rcore-os/zCore --recursive
```
## Testing
### LibOS Mode Testing
#### Zircon related
@ -148,6 +157,7 @@ cd scripts && python3 libos-libc-tests.py
```
### Bare-metal Mode Testing
#### Zircon related
Run Zircon official core-tests on bare-metal:
@ -167,6 +177,7 @@ cd scripts && python3 core-tests.py
#### x86-64 Linux related
Run Linux musl libc-tests for CI:
```sh
## Prepare rootfs with libc-test apps
make baremetal-test-img
@ -184,6 +195,7 @@ You can use [`scripts/baremetal-libc-test-ones.py`](./scripts/baremetal-libc-tes
#### riscv-64 Linux related
Run Linux musl libc-tests for CI:
```sh
## Prepare rootfs with libc-test & oscomp apps
make riscv-image
@ -192,25 +204,28 @@ cd scripts && python3 baremetal-test-riscv64.py
##
```
You can use[ `scripts/baremetal-libc-test-ones-riscv64.py`](./scripts/baremetal-libc-test-ones-riscv64.py) & [`scripts/linux/baremetal-test-ones-rv64.txt`](scripts/linux/baremetal-test-ones-rv64.txt)to test
You can use[scripts/baremetal-libc-test-ones-riscv64.py](./scripts/baremetal-libc-test-ones-riscv64.py) & [`scripts/linux/baremetal-test-ones-rv64.txt`](scripts/linux/baremetal-test-ones-rv64.txt)to test
specified apps.
[`scripts/linux/baremetal-test-fail-riscv64.txt`](./scripts/linux/baremetal-test-fail-riscv64.txt)includes all failed riscv-64 apps (We need YOUR HELP to fix bugs!)
## Graph/Game
snake game: https://github.com/rcore-os/rcore-user/blob/master/app/src/snake.c
snake game: <https://github.com/rcore-os/rcore-user/blob/master/app/src/snake.c>
### Step1: compile usr app
We can use musl-gcc compile it in x86_64 mode
### Step2: change zcore for run snake app first.
change zCore/zCore/main.rs L176
vec!["/bin/busybox".into(), "sh".into()]
TO
vec!["/bin/snake".into(), "sh".into()]
### Step3: prepare root fs image, run zcore in linux-bare-metal mode
exec:
```sh
@ -235,12 +250,15 @@ Operation
- `Middle`: Pause/Resume
## Doc
```
make doc
```
### RISC-V 64 porting info
- [porting riscv64 doc](./docs/porting-rv64.md)
## Components
### Overview
@ -260,4 +278,5 @@ make doc
| Exception Handling | Interrupt | Signal |
### Small Goal & Little Plans
- https://github.com/rcore-os/zCore/wiki/Plans
- <https://github.com/rcore-os/zCore/wiki/Plans>

74
docs/Manual.md Normal file
View File

@ -0,0 +1,74 @@
# zCore 项目使用指南
## 预定功能
预定功能指的是 zCore 作为一个项目,为开发者和用户常用操作提供的封装。
由于历史原因,目前预定功能分为顶层预定功能和内核预定功能。
所有顶层提供的预定功能都定义于 [顶层 Makefile](../Makefile)
并且所有预定功能最终都将移动到顶层。
## 常规操作流程
对于一般开发者和用户,可以按以下步骤设置 zCore 项目。
1. 先决条件
目前受关注的开发环境为较新版本的 Ubuntu建议使用 Ubuntu20.04 或 Ubuntu22.04。
本文假设读者使用二者之一。
若不需要烧写到物理硬件,使用 WSL2 或其他虚拟机的操作与真机并无不同之处。
在开始之前,确保你的计算机上安装了 git 和 rustup。要在虚拟环境开发或测试需要 QEMU。
2. 克隆项目
```bash
git clone https://github.com/rcore-os/zCore.git
```
3. 初始化存储库
```bash
make setup
```
4. 保持更新
```bash
make update
```
5. 探索更多操作
```bash
make help
```
## Linux 模式
zCore 根据向用户提供的系统调用的不同,可分为 zircon 模式和 linux 模式。
要以 linux 模式启动,需要先构建 linux 的启动文件系统。
这个指令构建适于 x86_64 架构的启动文件系统。
```bash
make rootfs ARCH=x86_64
```
这个指令构建适于 riscv64 架构的启动文件系统。
```bash
make rootfs ARCH=riscv64
```
要执行 musl-libc 测试集,需要向文件系统中添加 libc 测试集:
```bash
make libc-test <ARCH=?>
```
要以裸机模式启动 zCore需要构造将放到设备或虚拟环境中的镜像文件
```bash
make image <ARCH=?>
```

View File

@ -56,6 +56,4 @@ x2apic = "0.4"
x86_64 = "0.14"
[target.'cfg(any(target_arch = "riscv32", target_arch = "riscv64"))'.dependencies]
riscv = { git = "https://github.com/rust-embedded/riscv", rev = "cd31989", features = [
"inline-asm",
] }
riscv = "0.8"

View File

@ -75,9 +75,7 @@ x86-smpboot = { git = "https://github.com/rcore-os/x86-smpboot", rev = "1069df3"
# Bare-metal mode on riscv64
[target.'cfg(all(target_os = "none", target_arch = "riscv64"))'.dependencies]
riscv = { git = "https://github.com/rust-embedded/riscv", rev = "cd31989", features = [
"inline-asm",
] }
riscv = "0.8"
[target.'cfg(target_arch = "aarch64")'.dependencies]
tock-registers = "0.7"

View File

@ -1,4 +1,4 @@
[toolchain]
channel = "nightly-2022-01-20"
components = ["rust-src", "llvm-tools-preview", "rustfmt", "clippy"]
targets = ["riscv64gc-unknown-none-elf"]
targets = ["riscv64imac-unknown-none-elf"]

View File

@ -11,8 +11,12 @@ build = "build.rs"
[dependencies]
clap = { version = "3.1", features = ["derive"] }
clap-verbosity-flag = "1.0"
dircpy = "0.3.9"
dircpy = "0.3"
rand = "0.8"
shadow-rs = "0.11"
rcore-fs = { git = "https://github.com/rcore-os/rcore-fs", rev = "1a3246b" }
rcore-fs-sfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "1a3246b" }
rcore-fs-fuse = { git = "https://github.com/rcore-os/rcore-fs", rev = "1a3246b" }
[build-dependencies]
shadow-rs = "0.11"

View File

@ -1,8 +1,11 @@
use super::{dir, git, ALPINE_ROOTFS_VERSION, ALPINE_WEBSITE};
use clap::{Args, Subcommand};
use crate::{
dir,
download::{git_clone, wget},
CommandExt, ALPINE_ROOTFS_VERSION, ALPINE_WEBSITE,
};
use dircpy::copy_dir;
use std::{
ffi::OsStr,
ffi::{OsStr, OsString},
fs,
io::Write,
path::{Path, PathBuf},
@ -10,7 +13,7 @@ use std::{
};
#[derive(Args)]
pub struct Arch {
pub(super) struct Arch {
#[clap(subcommand)]
command: ArchCommands,
}
@ -24,6 +27,167 @@ enum ArchCommands {
}
impl Arch {
/// 构造启动内存文件系统 rootfs。
///
/// 将在文件系统中放置必要的库文件,并下载用于交叉编译的工具链。
pub fn rootfs(&self, clear: bool) {
self.wget_alpine();
match self.command {
ArchCommands::Riscv64 => {
const DIR: &str = "riscv_rootfs";
const ARCH: &str = "riscv64";
let dir = Path::new(DIR);
if dir.is_dir() && !clear {
return;
}
dir::clear(dir).unwrap();
let tar = dir::detect(&format!("prebuilt/linux/{ARCH}"), "minirootfs").unwrap();
Tar::xf(&tar, Some(DIR))
.args(&["--strip-components", "1"])
.join();
Command::new("ln")
.args(&["-s", "busybox", "riscv_rootfs/bin/ls"])
.status()
.unwrap()
.exit_ok()
.expect("FAILED: ln -s busybox riscv_rootfs/bin/ls");
}
ArchCommands::X86_64 => {
const DIR: &str = "rootfs";
const ARCH: &str = "x86_64";
let dir = Path::new(DIR);
if dir.is_dir() && !clear {
return;
}
dir::clear(DIR).unwrap();
let tar = dir::detect(&format!("prebuilt/linux/{ARCH}"), "minirootfs").unwrap();
Tar::xf(&tar, Some(DIR)).join();
// libc-libos.so (convert syscall to function call) is from https://github.com/rcore-os/musl/tree/rcore
fs::copy(
"prebuilt/linux/libc-libos.so",
format!("{DIR}/lib/ld-musl-{ARCH}.so.1"),
)
.unwrap();
{
const TEST_DIR: &str = "linux-syscall/test";
const DEST_DIR: &str = "rootfs/bin/";
// for linux syscall tests
fs::read_dir(TEST_DIR)
.unwrap()
.filter_map(|res| res.ok())
.map(|entry| entry.path())
.filter(|path| path.extension().map_or(false, |ext| ext == OsStr::new("c")))
.for_each(|c| {
let o = format!(
"{DEST_DIR}/{}",
c.file_prefix().and_then(|s| s.to_str()).unwrap()
);
Command::new("gcc")
.arg(&c)
.args(&["-o", &o])
.arg("-Wl,--dynamic-linker=/lib/ld-musl-x86_64.so.1")
.status()
.unwrap()
.exit_ok()
.expect("FAILED: gcc {c:?}");
});
}
}
}
}
/// 将 libc-test 放入 rootfs。
pub fn libc_test(&self) {
self.rootfs(false);
git_clone(
"https://github.com/rcore-os/libc-test.git",
"ignored/libc-test",
);
match self.command {
ArchCommands::Riscv64 => {
const DIR: &str = "riscv_rootfs/libc-test";
const PRE: &str = "riscv_rootfs/libc-test-prebuild";
fs::rename(DIR, PRE).unwrap();
copy_dir("ignored/libc-test", DIR).unwrap();
fs::copy(format!("{DIR}/config.mak.def"), format!("{DIR}/config.mak")).unwrap();
Make::new(None)
.env("ARCH", "riscv64")
.env("CROSS_COMPILE", "riscv64-linux-musl-")
.env("PATH", riscv64_linux_musl_cross())
.current_dir(DIR)
.join();
fs::copy(
format!("{PRE}/functional/tls_align-static.exe"),
format!("{DIR}/src/functional/tls_align-static.exe"),
)
.unwrap();
dir::rm(PRE).unwrap();
}
ArchCommands::X86_64 => {
const DIR: &str = "rootfs/libc-test";
dir::rm(DIR).unwrap();
copy_dir("ignored/libc-test", DIR).unwrap();
fs::copy(format!("{DIR}/config.mak.def"), format!("{DIR}/config.mak")).unwrap();
fs::OpenOptions::new()
.append(true)
.open(format!("{DIR}/config.mak"))
.unwrap()
.write_all(b"CC := musl-gcc\nAR := ar\nRANLIB := ranlib")
.unwrap();
Make::new(None).current_dir(DIR).join();
}
}
}
/// 生成镜像。
pub fn image(&self) {
self.rootfs(false);
let image = match self.command {
ArchCommands::Riscv64 => {
const ARCH: &str = "riscv64";
let image = format!("zCore/{ARCH}.img");
fuse("riscv_rootfs", &image);
image
}
ArchCommands::X86_64 => {
const ARCH: &str = "x86_64";
const TMP_ROOTFS: &str = "/tmp/rootfs";
const ROOTFS_LIB: &str = "rootfs/lib";
// ld-musl-x86_64.so.1 替换为适用 bare-matel 的版本
dir::clear(TMP_ROOTFS).unwrap();
let tar = dir::detect(&format!("prebuilt/linux/{ARCH}"), "minirootfs").unwrap();
Tar::xf(&tar, Some(TMP_ROOTFS)).join();
dir::clear(ROOTFS_LIB).unwrap();
fs::copy(
format!("{TMP_ROOTFS}/lib/ld-musl-x86_64.so.1"),
format!("{ROOTFS_LIB}/ld-musl-x86_64.so.1"),
)
.unwrap();
let image = format!("zCore/{ARCH}.img");
fuse("rootfs", &image);
fs::copy(
"prebuilt/linux/libc-libos.so",
format!("{ROOTFS_LIB}/ld-musl-x86_64.so.1"),
)
.unwrap();
image
}
};
Command::new("qemu-img")
.args(&["resize", &image, "+5M"])
.status()
.unwrap()
.exit_ok()
.expect("FAILED: qemu-img resize");
}
/// 获取 alpine 镜像。
fn wget_alpine(&self) {
let (local_path, web_url) = match self.command {
@ -56,285 +220,107 @@ impl Arch {
};
fs::create_dir_all(local_path.parent().unwrap()).unwrap();
#[rustfmt::skip]
let wget = Command::new("wget")
.arg(&web_url)
.arg("-O").arg(local_path)
.status();
if !wget.unwrap().success() {
panic!("FAILED: wget {web_url}");
}
}
/// 构造启动内存文件系统 rootfs。
///
/// 将在文件系统中放置必要的库文件,并下载用于交叉编译的工具链。
pub fn rootfs(&self) {
self.wget_alpine();
match self.command {
ArchCommands::Riscv64 => {
const DIR: &str = "riscv_rootfs";
const ARCH: &str = "riscv64";
{
dir::clear(DIR).unwrap();
let tar = dir::detect(&format!("prebuilt/linux/{ARCH}"), "minirootfs").unwrap();
#[rustfmt::skip]
let res = tar_xf(&tar, Some(DIR))
.arg("--strip-components").arg("1")
.status().unwrap();
if !res.success() {
panic!("FAILED: tar xf {tar:?}");
}
}
{
#[rustfmt::skip]
let ln = Command::new("ln")
.arg("-s").arg("busybox").arg("riscv_rootfs/bin/ls")
.status().unwrap();
if !ln.success() {
panic!("FAILED: ln -s busybox riscv_rootfs/bin/ls");
}
}
}
ArchCommands::X86_64 => {
const DIR: &str = "rootfs";
const ARCH: &str = "x86_64";
{
dir::clear(DIR).unwrap();
let tar = dir::detect(&format!("prebuilt/linux/{ARCH}"), "minirootfs").unwrap();
if !tar_xf(&tar, Some(DIR)).status().unwrap().success() {
panic!("FAILED: tar xf {tar:?}");
}
}
{
// libc-libos.so (convert syscall to function call) is from https://github.com/rcore-os/musl/tree/rcore
fs::copy(
"prebuilt/linux/libc-libos.so",
format!("{DIR}/lib/ld-musl-{ARCH}.so.1"),
)
.unwrap();
}
{
const TEST_DIR: &str = "linux-syscall/test";
const DEST_DIR: &str = "rootfs/bin/";
// for linux syscall tests
fs::read_dir(TEST_DIR)
.unwrap()
.filter_map(|res| res.ok())
.map(|entry| entry.path())
.filter(|path| path.extension().map_or(false, |ext| ext == OsStr::new("c")))
.for_each(|c| {
let o = format!(
"{DEST_DIR}/{}",
c.file_prefix().and_then(|s| s.to_str()).unwrap()
);
#[rustfmt::skip]
let gcc = Command::new("gcc").arg(&c)
.arg("-o").arg(o)
.arg("-Wl,--dynamic-linker=/lib/ld-musl-x86_64.so.1")
.status().unwrap();
if !gcc.success() {
panic!("FAILED: gcc {c:?}");
}
});
}
}
}
}
/// 将 libc-test 放入 rootfs。
pub fn libc_test(&self) {
clone_libc_test();
match self.command {
ArchCommands::Riscv64 => {
const DIR: &str = "riscv_rootfs/libc-test";
const PRE: &str = "riscv_rootfs/libc-test-prebuild";
riscv64_linux_musl_cross();
fs::rename(DIR, PRE).unwrap();
copy_dir("ignored/libc-test", DIR).unwrap();
fs::copy(format!("{DIR}/config.mak.def"), format!("{DIR}/config.mak")).unwrap();
let make = Command::new("make")
.arg("-j")
.env("ARCH", "riscv64")
.env("CROSS_COMPILE", "riscv64-linux-musl-")
.current_dir(DIR)
.status();
if !make.unwrap().success() {
panic!("FAILED: make -j");
}
fs::copy(
format!("{PRE}/functional/tls_align-static.exe"),
format!("{DIR}/src/functional/tls_align-static.exe"),
)
.unwrap();
dir::rm(PRE).unwrap();
}
ArchCommands::X86_64 => {
const DIR: &str = "rootfs/libc-test";
dir::rm(DIR).unwrap();
copy_dir("ignored/libc-test", DIR).unwrap();
fs::copy(format!("{DIR}/config.mak.def"), format!("{DIR}/config.mak")).unwrap();
fs::OpenOptions::new()
.append(true)
.open(format!("{DIR}/config.mak"))
.unwrap()
.write_all(b"CC := musl-gcc\nAR := ar\nRANLIB := ranlib")
.unwrap();
if !Command::new("make")
.arg("-j")
.current_dir(DIR)
.status()
.unwrap()
.success()
{
panic!("FAILED: make -j");
}
}
}
}
/// 生成镜像。
pub fn image(&self) {
install_fs_fuse();
let image = match self.command {
ArchCommands::Riscv64 => {
const ARCH: &str = "riscv64";
let image = format!("zCore/{ARCH}.img");
#[rustfmt::skip]
let fuse = Command::new("rcore-fs-fuse")
.arg(&image).arg("riscv_rootfs").arg("zip")
.status().unwrap();
if !fuse.success() {
panic!("FAILED: rcore-fs-fuse");
}
image
}
ArchCommands::X86_64 => {
const ARCH: &str = "x86_64";
const TMP_ROOTFS: &str = "/tmp/rootfs";
const ROOTFS_LIB: &str = "rootfs/lib";
// ld-musl-x86_64.so.1 替换为适用 bare-matel 的版本
dir::clear(TMP_ROOTFS).unwrap();
let tar = dir::detect(&format!("prebuilt/linux/{ARCH}"), "minirootfs").unwrap();
if !tar_xf(&tar, Some(TMP_ROOTFS)).status().unwrap().success() {
panic!("FAILED: tar xf {tar:?}");
}
dir::clear(ROOTFS_LIB).unwrap();
fs::copy(
format!("{TMP_ROOTFS}/lib/ld-musl-x86_64.so.1"),
format!("{ROOTFS_LIB}/ld-musl-x86_64.so.1"),
)
.unwrap();
let image = format!("zCore/{ARCH}.img");
#[rustfmt::skip]
let fuse = Command::new("rcore-fs-fuse")
.arg(&image).arg("rootfs").arg("zip")
.status().unwrap();
if !fuse.success() {
panic!("FAILED: rcore-fs-fuse");
}
// ld-musl-x86_64.so.1 替换为适用 libos 的版本
// # libc-libos.so (convert syscall to function call) is from https://github.com/rcore-os/musl/tree/rcore
fs::copy(
"prebuilt/linux/libc-libos.so",
format!("{ROOTFS_LIB}/ld-musl-x86_64.so.1"),
)
.unwrap();
image
}
};
#[rustfmt::skip]
let resize = Command::new("qemu-img")
.arg("resize").arg(image).arg("+5M")
.status().unwrap();
if !resize.success() {
panic!("FAILED: qemu-img resize");
}
wget(&web_url, &local_path);
}
}
/// 构造将归档文件 `src` 释放到 `dst` 目录下的命令。
///
/// 本身不会产生异常,因为命令还没有执行。
/// 但若 `src` 不是存在的归档文件,或 `dst` 不是存在的目录,将在命令执行时产生对应异常。
fn tar_xf(src: &impl AsRef<OsStr>, dst: Option<&str>) -> Command {
let mut cmd = Command::new("tar");
cmd.arg("xf").arg(src);
if let Some(dst) = dst {
cmd.arg("-C").arg(dst);
}
cmd
}
struct Make(Command);
/// 安装 rcore-fs-fuse。
fn install_fs_fuse() {
if let Ok(true) = Command::new("rcore-fs-fuse")
.arg("--version")
.output()
.map(|out| out.stdout.starts_with(b"rcore-fs-fuse"))
{
println!("Rcore-fs-fuse is already installed.");
return;
}
#[rustfmt::skip]
let install = Command::new("cargo")
.arg("install").arg("rcore-fs-fuse")
.arg("--git").arg("https://github.com/rcore-os/rcore-fs")
.arg("--rev").arg("1a3246b")
.arg("--force")
.status();
if !install.unwrap().success() {
panic!("FAILED: install rcore-fs-fuse");
impl AsRef<Command> for Make {
fn as_ref(&self) -> &Command {
&self.0
}
}
/// 克隆 libc-test.
fn clone_libc_test() {
const DIR: &str = "ignored/libc-test";
const URL: &str = "https://github.com/rcore-os/libc-test.git";
impl AsMut<Command> for Make {
fn as_mut(&mut self) -> &mut Command {
&mut self.0
}
}
if Path::new(DIR).is_dir() {
let pull = git::pull().current_dir(DIR).status();
if !pull.unwrap().success() {
panic!("FAILED: git pull");
impl CommandExt for Make {}
impl Make {
fn new(j: Option<usize>) -> Self {
let mut make = Self(Command::new("make"));
match j {
Some(0) => {}
Some(j) => {
make.arg(format!("-j{j}"));
}
None => {
make.arg("-j");
}
}
} else {
dir::clear(DIR).unwrap();
let clone = git::clone(URL, Some(DIR)).status();
if !clone.unwrap().success() {
panic!("FAILED: git clone {URL}");
make
}
}
struct Tar(Command);
impl AsRef<Command> for Tar {
fn as_ref(&self) -> &Command {
&self.0
}
}
impl AsMut<Command> for Tar {
fn as_mut(&mut self) -> &mut Command {
&mut self.0
}
}
impl CommandExt for Tar {}
impl Tar {
fn xf(src: &impl AsRef<OsStr>, dst: Option<&str>) -> Self {
let mut cmd = Command::new("tar");
cmd.arg("xf").arg(src);
if let Some(dst) = dst {
cmd.arg("-C").arg(dst);
}
Self(cmd)
}
}
/// 下载 riscv64-musl 工具链。
fn riscv64_linux_musl_cross() {
fn riscv64_linux_musl_cross() -> OsString {
const DIR: &str = "ignored";
const NAME: &str = "riscv64-linux-musl-cross";
let dir = format!("{DIR}/{NAME}");
let tgz = format!("{dir}.tgz");
if !Path::new(&tgz).exists() {
let url = format!("https://musl.cc/{NAME}.tgz");
#[rustfmt::skip]
let wget = Command::new("wget")
.arg(&url)
.arg("-O").arg(&tgz)
.status().unwrap();
if !wget.success() {
panic!("FAILED: wget {url}");
}
}
wget(&format!("https://musl.cc/{NAME}.tgz"), &tgz);
dir::rm(&dir).unwrap();
if !tar_xf(&tgz, Some(DIR)).status().unwrap().success() {
panic!("FAILED: tar xf {tgz}");
Tar::xf(&tgz, Some(DIR)).join();
// 将交叉工具链加入 PATH 环境变量
let mut path = OsString::new();
if let Ok(current) = std::env::var("PATH") {
path.push(current);
path.push(":");
}
path.push(std::env::current_dir().unwrap());
path.push("/ignored/riscv64-linux-musl-cross/bin");
path
}
/// 制作镜像。
fn fuse(dir: impl AsRef<Path>, image: impl AsRef<Path>) {
use rcore_fs::vfs::FileSystem;
use rcore_fs_fuse::zip::zip_dir;
use rcore_fs_sfs::SimpleFileSystem;
use std::sync::{Arc, Mutex};
let file = fs::OpenOptions::new()
.read(true)
.write(true)
.create(true)
.truncate(true)
.open(image)
.expect("failed to open image");
const MAX_SPACE: usize = 0x1000 * 0x1000 * 1024; // 1G
let fs = SimpleFileSystem::create(Arc::new(Mutex::new(file)), MAX_SPACE)
.expect("failed to create sfs");
zip_dir(dir.as_ref(), fs.root_inode()).expect("failed to zip fs");
}

75
xtask/src/cargo.rs Normal file
View File

@ -0,0 +1,75 @@
use crate::CommandExt;
use std::{ffi::OsStr, process::Command};
pub(crate) struct Cargo {
cmd: Command,
}
impl AsRef<Command> for Cargo {
fn as_ref(&self) -> &Command {
&self.cmd
}
}
impl AsMut<Command> for Cargo {
fn as_mut(&mut self) -> &mut Command {
&mut self.cmd
}
}
impl CommandExt for Cargo {}
impl Cargo {
fn new(sub: &(impl AsRef<OsStr> + ?Sized)) -> Self {
let mut git = Self {
cmd: Command::new("cargo"),
};
git.arg(sub);
git
}
pub fn update() -> Self {
Self::new("update")
}
pub fn fmt() -> Self {
Self::new("fmt")
}
pub fn clippy() -> Self {
Self::new("clippy")
}
pub fn all_features(&mut self) -> &mut Self {
self.arg("--all-features");
self
}
pub fn features<S, I>(&mut self, default: bool, feats: I) -> &mut Self
where
I: IntoIterator<Item = S>,
S: AsRef<OsStr>,
{
if !default {
self.arg("--no-default-features");
}
let mut iter = feats.into_iter();
if let Some(feat) = iter.next() {
self.arg("--features");
let mut feats = feat.as_ref().to_os_string();
for feat in iter {
feats.push(" ");
feats.push(feat);
}
self.arg(feats);
}
self
}
pub fn target(&mut self, target: impl AsRef<OsStr>) -> &mut Self {
self.arg("--target").arg(target);
self
}
}

51
xtask/src/download.rs Normal file
View File

@ -0,0 +1,51 @@
use crate::{dir, git::Git, CommandExt};
use std::{ffi::OsStr, fs, path::Path, process::Command};
pub(crate) fn wget(url: impl AsRef<OsStr>, dst: impl AsRef<Path>) {
let dst = dst.as_ref();
if dst.exists() {
return;
}
let tmp: usize = rand::random();
let tmp = format!("/tmp/{tmp}");
let status = Command::new("wget")
.arg(&url)
.args(&["-O", &tmp])
.status()
.unwrap();
if status.success() {
fs::rename(&tmp, dst).unwrap();
} else {
dir::rm(&tmp).unwrap();
panic!(
"Failed with code {}: wget {:?}",
status.code().unwrap(),
url.as_ref()
);
}
}
pub(crate) fn git_clone(repo: impl AsRef<OsStr>, dst: impl AsRef<Path>) {
let dst = dst.as_ref();
if dst.is_dir() {
Git::pull().current_dir(dst).join();
return;
}
let tmp: usize = rand::random();
let tmp = format!("/tmp/{tmp}");
let mut git = Git::clone(repo, Some(&tmp));
let status = git.status();
if status.success() {
dir::clear(dst).unwrap();
fs::rename(&tmp, dst).unwrap();
} else {
dir::rm(&tmp).unwrap();
panic!(
"Failed with code {}: {:?}",
status.code().unwrap(),
git.info()
);
}
}

View File

@ -1,51 +1,66 @@
//! 操作 git。
use crate::CommandExt;
use std::{ffi::OsStr, process::Command};
fn git(sub: &(impl AsRef<OsStr> + ?Sized)) -> Command {
let mut cmd = Command::new("git");
cmd.arg(sub);
cmd
pub(super) struct Git {
cmd: Command,
}
/// git lfs ...
pub fn lfs() -> Command {
git("lfs")
}
/// git config [--global] ...
pub fn config(global: bool) -> Command {
let mut cmd = git("config");
if global {
cmd.arg("--global");
};
cmd
}
/// git clone [dir] ...
pub fn clone(
repo: &(impl AsRef<OsStr> + ?Sized),
dir: Option<&(impl AsRef<OsStr> + ?Sized)>,
) -> Command {
let mut cmd = git("clone");
cmd.arg(repo);
if let Some(dir) = dir {
cmd.arg(dir);
impl AsRef<Command> for Git {
fn as_ref(&self) -> &Command {
&self.cmd
}
cmd
}
/// git pull ...
pub fn pull() -> Command {
git("pull")
}
/// git submodule update --init.
pub fn submodule_update(init: bool) -> Command {
let mut cmd = git("submodule");
cmd.arg("update");
if init {
cmd.arg("--init");
impl AsMut<Command> for Git {
fn as_mut(&mut self) -> &mut Command {
&mut self.cmd
}
}
impl CommandExt for Git {}
impl Git {
fn new(sub: impl AsRef<OsStr>) -> Self {
let mut git = Self {
cmd: Command::new("git"),
};
git.arg(sub);
git
}
pub fn lfs() -> Self {
Self::new("lfs")
}
pub fn config(global: bool) -> Self {
let mut git = Self::new("config");
if global {
git.arg("--global");
};
git
}
pub fn clone(repo: impl AsRef<OsStr>, dir: Option<impl AsRef<OsStr>>) -> Self {
let mut git = Self::new("clone");
git.arg(repo);
if let Some(dir) = dir {
git.arg(dir);
}
git
}
pub fn pull() -> Self {
Self::new("pull")
}
pub fn submodule_update(init: bool) -> Self {
let mut git = Self::new("submodule");
git.arg("update");
if init {
git.arg("--init");
}
git
}
cmd
}

View File

@ -1,15 +1,29 @@
#![feature(path_file_prefix)]
#![feature(exit_status_error)]
use clap::{Args, Parser, Subcommand};
#[macro_use]
extern crate clap;
use clap::Parser;
use clap_verbosity_flag::Verbosity;
use std::{fs::read_to_string, net::Ipv4Addr, process::Command};
use std::{
ffi::{OsStr, OsString},
fs::read_to_string,
net::Ipv4Addr,
path::Path,
process::{Command, ExitStatus},
};
mod arch;
mod cargo;
mod dir;
mod download;
mod dump;
mod git;
use arch::Arch;
use cargo::Cargo;
use git::Git;
const ALPINE_WEBSITE: &str = "https://dl-cdn.alpinelinux.org/alpine/v3.12/releases";
const ALPINE_ROOTFS_VERSION: &str = "3.12.0";
@ -95,7 +109,7 @@ fn main() {
}
Commands::UpdateAll => update_all(),
Commands::CheckStyle => check_style(),
Commands::Rootfs(arch) => arch.rootfs(),
Commands::Rootfs(arch) => arch.rootfs(true),
Commands::LibcTest(arch) => arch.libc_test(),
Commands::Image(arch) => arch.image(),
Commands::Test => todo!(),
@ -104,48 +118,33 @@ fn main() {
/// 初始化 LFS。
fn make_git_lfs() {
if !git::lfs()
if !Git::lfs()
.arg("version")
.as_mut()
.output()
.map_or(false, |out| out.stdout.starts_with(b"git-lfs/"))
{
panic!("Cannot find git lfs, see https://git-lfs.github.com/ for help.");
}
if !git::lfs().arg("install").status().unwrap().success() {
panic!("FAILED: git lfs install")
}
if !git::lfs().arg("pull").status().unwrap().success() {
panic!("FAILED: git lfs pull")
}
Git::lfs().arg("install").join();
Git::lfs().arg("pull").join();
}
/// 更新子项目。
fn git_submodule_update(init: bool) {
if !git::submodule_update(init).status().unwrap().success() {
panic!("FAILED: git submodule update --init");
}
Git::submodule_update(init).join();
}
/// 更新工具链和依赖。
fn update_all() {
git_submodule_update(false);
if !Command::new("rustup")
Command::new("rustup")
.arg("update")
.status()
.unwrap()
.success()
{
panic!("FAILED: rustup update");
}
if !Command::new("cargo")
.arg("update")
.status()
.unwrap()
.success()
{
panic!("FAILED: cargo update");
}
.exit_ok()
.expect("FAILED: rustup update");
Cargo::update().join();
}
/// 设置 git 代理。
@ -159,81 +158,108 @@ fn set_git_proxy(global: bool, port: u16) {
})
.expect("FAILED: detect DNS");
let proxy = format!("socks5://{dns}:{port}");
#[rustfmt::skip]
let git = git::config(global)
.arg("http.proxy").arg(&proxy)
.status().unwrap();
if !git.success() {
panic!("FAILED: git config --unset http.proxy");
}
#[rustfmt::skip]
let git = git::config(global)
.arg("https.proxy").arg(&proxy)
.status().unwrap();
if !git.success() {
panic!("FAILED: git config --unset https.proxy");
}
Git::config(global).args(&["http.proxy", &proxy]).join();
Git::config(global).args(&["http.proxy", &proxy]).join();
println!("git proxy = {proxy}");
}
/// 移除 git 代理。
fn unset_git_proxy(global: bool) {
#[rustfmt::skip]
let git = git::config(global)
.arg("--unset").arg("http.proxy")
.status().unwrap();
if !git.success() {
panic!("FAILED: git config --unset http.proxy");
}
#[rustfmt::skip]
let git = git::config(global)
.arg("--unset").arg("https.proxy")
.status().unwrap();
if !git.success() {
panic!("FAILED: git config --unset https.proxy");
}
Git::config(global).args(&["--unset", "http.proxy"]).join();
Git::config(global).args(&["--unset", "https.proxy"]).join();
println!("git proxy =");
}
/// 风格检查。
fn check_style() {
println!("fmt -----------------------------------------");
#[rustfmt::skip]
Command::new("cargo").arg("fmt")
.arg("--all")
.arg("--")
.arg("--check")
.status()
.unwrap();
Cargo::fmt().arg("--all").arg("--").arg("--check").join();
println!("clippy --------------------------------------");
#[rustfmt::skip]
Command::new("cargo").arg("clippy")
.arg("--all-features")
.status()
.unwrap();
Cargo::clippy().all_features().join();
println!("clippy x86_64 zircon smp=1 ------------------");
#[rustfmt::skip]
Command::new("cargo").arg("clippy")
.arg("--no-default-features")
.arg("--features").arg("zircon")
.arg("--target").arg("x86_64.json")
.arg("-Z").arg("build-std=core,alloc")
.arg("-Z").arg("build-std-features=compiler-builtins-mem")
Cargo::clippy()
.features(false, &["zircon"])
.target("x86_64.json")
.args(&["-Z", "build-std=core,alloc"])
.args(&["-Z", "build-std-features=compiler-builtins-mem"])
.current_dir("zCore")
.env("SMP", "1")
.status()
.unwrap();
.join();
println!("clippy riscv64 linux smp=4 ------------------");
#[rustfmt::skip]
Command::new("cargo").arg("clippy")
.arg("--no-default-features")
.arg("--features").arg("linux board-qemu")
.arg("--target").arg("riscv64.json")
.arg("-Z").arg("build-std=core,alloc")
.arg("-Z").arg("build-std-features=compiler-builtins-mem")
Cargo::clippy()
.features(false, &["linux", "board-qemu"])
.target("riscv64.json")
.args(&["-Z", "build-std=core,alloc"])
.args(&["-Z", "build-std-features=compiler-builtins-mem"])
.current_dir("zCore")
.env("SMP", "4")
.env("PLATFORM", "board-qemu")
.status()
.unwrap();
.join();
}
trait CommandExt: AsRef<Command> + AsMut<Command> {
fn arg(&mut self, s: impl AsRef<OsStr>) -> &mut Self {
self.as_mut().arg(s);
self
}
fn args<I, S>(&mut self, args: I) -> &mut Self
where
I: IntoIterator<Item = S>,
S: AsRef<OsStr>,
{
for arg in args {
self.arg(arg);
}
self
}
fn current_dir(&mut self, dir: impl AsRef<Path>) -> &mut Self {
self.as_mut().current_dir(dir);
self
}
fn env(&mut self, key: impl AsRef<OsStr>, val: impl AsRef<OsStr>) -> &mut Self {
self.as_mut().env(key, val);
self
}
fn status(&mut self) -> ExitStatus {
self.as_mut().status().unwrap()
}
fn info(&self) -> OsString {
let cmd = self.as_ref();
let mut msg = OsString::new();
if let Some(dir) = cmd.get_current_dir() {
msg.push("cd ");
msg.push(dir);
msg.push(" && ");
}
msg.push(cmd.get_program());
for a in cmd.get_args() {
msg.push(" ");
msg.push(a);
}
for (k, v) in cmd.get_envs() {
msg.push(" ");
msg.push(k);
if let Some(v) = v {
msg.push("=");
msg.push(v);
}
}
msg
}
fn join(&mut self) {
let status = self.status();
if !status.success() {
panic!(
"Failed with code {}: {:?}",
status.code().unwrap(),
self.info()
);
}
}
}

View File

@ -83,9 +83,7 @@ buddy_system_allocator = "0.8"
# RISC-V
[target.'cfg(any(target_arch = "riscv32", target_arch = "riscv64"))'.dependencies]
r0 = "1"
riscv = { git = "https://github.com/rust-embedded/riscv", rev = "cd31989", features = [
"inline-asm",
] }
riscv = "0.8"
# Bare-metal mode on x86_64
[target.'cfg(all(target_os = "none", target_arch = "x86_64"))'.dependencies]
@ -95,4 +93,4 @@ rboot = { git = "https://github.com/rcore-os/rboot.git", rev = "39d6e24", defaul
# Bare-metal mode on x86_64
[target.'cfg(all(target_os = "none", not(target_arch = "x86_64")))'.dependencies]
serde = { version = "1.0", default-features = false, features = ["derive"] }
serde-device-tree = { git = "https://github.com/YdrMaster/serde-device-tree.git", rev = "af8605f", default-features = false }
serde-device-tree = { git = "https://github.com/rustsbi/serde-device-tree.git", rev = "114679a", default-features = false }