forked from rcore-os/zCore
merge upstream
This commit is contained in:
commit
d2acb4386e
|
@ -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
|
||||
|
|
|
@ -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: |
|
||||
|
|
|
@ -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__
|
||||
|
|
84
Makefile
84
Makefile
|
@ -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
|
||||
|
||||
|
|
47
README.md
47
README.md
|
@ -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>
|
||||
|
|
|
@ -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=?>
|
||||
```
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"]
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 }
|
||||
|
|
Loading…
Reference in New Issue