From 9d8316b9b690ef6fbb9fd6717edcd10f5c1ba3c8 Mon Sep 17 00:00:00 2001 From: YdrMaster Date: Thu, 12 May 2022 19:43:45 +0800 Subject: [PATCH] =?UTF-8?q?feat(xtask):=20=E4=BB=8E=E9=A1=B6=E5=B1=82?= =?UTF-8?q?=E5=90=AF=E5=8A=A8=20qemu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .cargo/config.toml | 4 ++ xtask/src/arch.rs | 89 ++++++++++++----------- xtask/src/{ => command}/cargo.rs | 12 +++- xtask/src/{ => command}/dir.rs | 0 xtask/src/{ => command}/download.rs | 2 +- xtask/src/{ => command}/git.rs | 4 +- xtask/src/{ => command}/make.rs | 2 +- xtask/src/command/mod.rs | 106 ++++++++++++++++++++++++++++ xtask/src/command/tar.rs | 29 ++++++++ xtask/src/main.rs | 104 +++------------------------ zCore/build.rs | 5 +- 11 files changed, 215 insertions(+), 142 deletions(-) rename xtask/src/{ => command}/cargo.rs (90%) rename xtask/src/{ => command}/dir.rs (100%) rename xtask/src/{ => command}/download.rs (96%) rename xtask/src/{ => command}/git.rs (96%) rename xtask/src/{ => command}/make.rs (95%) create mode 100644 xtask/src/command/mod.rs create mode 100644 xtask/src/command/tar.rs diff --git a/.cargo/config.toml b/.cargo/config.toml index 017fb019..44e98567 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -3,8 +3,12 @@ xtask = "run --package xtask --" git-proxy = "xtask git-proxy" setup = "xtask setup" update-all = "xtask update-all" + check-style = "xtask check-style" + rootfs = "xtask rootfs" libc-test = "xtask libc-test" other-test = "xtask other-test" image = "xtask image" + +qemu = "xtask qemu" diff --git a/xtask/src/arch.rs b/xtask/src/arch.rs index cf5cd069..22547143 100644 --- a/xtask/src/arch.rs +++ b/xtask/src/arch.rs @@ -1,6 +1,9 @@ //! 平台相关的操作。 -use crate::{dir, download::wget, make::Make, CommandExt, ALPINE_ROOTFS_VERSION, ALPINE_WEBSITE}; +use crate::{ + command::{dir, download::wget, Cargo, CommandExt, Ext, Make, Tar}, + ALPINE_ROOTFS_VERSION, ALPINE_WEBSITE, +}; use dircpy::copy_dir; use std::{ ffi::{OsStr, OsString}, @@ -8,7 +11,6 @@ use std::{ io::Write, os::unix, path::{Path, PathBuf}, - process::Command, }; #[derive(Args)] @@ -156,15 +158,12 @@ impl Arch { .map(|entry| entry.path()) .filter(|path| path.extension().map_or(false, |ext| ext == OsStr::new("c"))) .for_each(|c| { - Command::new("gcc") + Ext::new("gcc") .arg(&c) .arg("-o") .arg(bin.join(c.file_prefix().unwrap())) .arg("-Wl,--dynamic-linker=/lib/ld-musl-x86_64.so.1") - .status() - .unwrap() - .exit_ok() - .expect("FAILED: gcc {c:?}"); + .invoke(); }); } } @@ -203,12 +202,49 @@ impl Arch { image } }; - Command::new("qemu-img") - .args(&["resize", &image, "+5M"]) - .status() - .unwrap() - .exit_ok() - .expect("FAILED: qemu-img resize"); + Ext::new("qemu-img") + .arg("resize") + .args(&["-f", "raw"]) + .arg(image) + .arg("+5M") + .invoke(); + } + + /// 在 qemu 中启动。 + pub fn qemu(&self) { + self.image(); + match self.command { + ArchCommands::Riscv64 => { + Cargo::build() + .package("zcore") + .features(false, &["linux", "board-qemu"]) + .target("zCore/riscv64.json") + .args(&["-Z", "build-std=core,alloc"]) + .args(&["-Z", "build-std-features=compiler-builtins-mem"]) + .release() + .invoke(); + Ext::new("rust-objcopy") + .arg("--binary-architecture=riscv64") + .arg("target/riscv64/release/zcore") + .arg("--strip-all") + .args(&["-O", "binary", "target/riscv64/release/zcore.bin"]) + .invoke(); + Ext::new("qemu-system-riscv64") + .args(&["-smp", "1"]) + .args(&["-machine", "virt"]) + .args(&["-bios", "default"]) + .args(&["-m", "512M"]) + .args(&["-serial", "mon:stdio"]) + .args(&["-kernel", "target/riscv64/release/zcore.bin"]) + .args(&["-initrd", "zCore/riscv64.img"]) + .args(&["-append", "\"LOG=warn\""]) + .args(&["-display", "none"]) + .arg("-no-reboot") + .arg("-nographic") + .invoke(); + } + ArchCommands::X86_64 => todo!(), + } } /// 下载并解压 minirootfs。 @@ -239,33 +275,6 @@ impl Arch { } } -struct Tar(Command); - -impl AsRef for Tar { - fn as_ref(&self) -> &Command { - &self.0 - } -} - -impl AsMut for Tar { - fn as_mut(&mut self) -> &mut Command { - &mut self.0 - } -} - -impl CommandExt for Tar {} - -impl Tar { - fn xf(src: &impl AsRef, dst: Option>) -> 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() -> OsString { const NAME: &str = "riscv64-linux-musl-cross"; diff --git a/xtask/src/cargo.rs b/xtask/src/command/cargo.rs similarity index 90% rename from xtask/src/cargo.rs rename to xtask/src/command/cargo.rs index 1bc6c200..7292b032 100644 --- a/xtask/src/cargo.rs +++ b/xtask/src/command/cargo.rs @@ -1,4 +1,4 @@ -use crate::CommandExt; +use super::CommandExt; use std::{ffi::OsStr, process::Command}; pub(crate) struct Cargo { @@ -44,6 +44,10 @@ impl Cargo { Self::new("doc") } + pub fn build() -> Self { + Self::new("build") + } + pub fn all_features(&mut self) -> &mut Self { self.arg("--all-features"); self @@ -72,7 +76,6 @@ impl Cargo { self } - #[allow(unused)] pub fn target(&mut self, target: impl AsRef) -> &mut Self { self.arg("--target").arg(target); self @@ -82,4 +85,9 @@ impl Cargo { self.arg("--package").arg(package); self } + + pub fn release(&mut self) -> &mut Self { + self.arg("--release"); + self + } } diff --git a/xtask/src/dir.rs b/xtask/src/command/dir.rs similarity index 100% rename from xtask/src/dir.rs rename to xtask/src/command/dir.rs diff --git a/xtask/src/download.rs b/xtask/src/command/download.rs similarity index 96% rename from xtask/src/download.rs rename to xtask/src/command/download.rs index c1782d3f..242cf040 100644 --- a/xtask/src/download.rs +++ b/xtask/src/command/download.rs @@ -1,4 +1,4 @@ -use crate::{dir, git::Git, CommandExt}; +use super::{dir, git::Git, CommandExt}; use std::{ffi::OsStr, fs, path::Path, process::Command}; pub(crate) fn wget(url: impl AsRef, dst: impl AsRef) { diff --git a/xtask/src/git.rs b/xtask/src/command/git.rs similarity index 96% rename from xtask/src/git.rs rename to xtask/src/command/git.rs index b84fade3..c555192e 100644 --- a/xtask/src/git.rs +++ b/xtask/src/command/git.rs @@ -1,9 +1,9 @@ //! 操作 git。 -use crate::CommandExt; +use super::CommandExt; use std::{ffi::OsStr, process::Command}; -pub(super) struct Git { +pub(crate) struct Git { cmd: Command, } diff --git a/xtask/src/make.rs b/xtask/src/command/make.rs similarity index 95% rename from xtask/src/make.rs rename to xtask/src/command/make.rs index ca0ae2c6..c9f68772 100644 --- a/xtask/src/make.rs +++ b/xtask/src/command/make.rs @@ -1,4 +1,4 @@ -use crate::CommandExt; +use super::CommandExt; use std::process::Command; pub(crate) struct Make(Command); diff --git a/xtask/src/command/mod.rs b/xtask/src/command/mod.rs new file mode 100644 index 00000000..fa4c94e2 --- /dev/null +++ b/xtask/src/command/mod.rs @@ -0,0 +1,106 @@ +use std::{ + ffi::{OsStr, OsString}, + path::Path, + process::{Command, ExitStatus}, +}; + +mod cargo; +pub mod dir; +pub mod download; +mod git; +mod make; +mod tar; + +pub(crate) use cargo::Cargo; +pub(crate) use git::Git; +pub(crate) use make::Make; +pub(crate) use tar::Tar; + +pub(crate) trait CommandExt: AsRef + AsMut { + fn arg(&mut self, s: impl AsRef) -> &mut Self { + self.as_mut().arg(s); + self + } + + fn args(&mut self, args: I) -> &mut Self + where + I: IntoIterator, + S: AsRef, + { + for arg in args { + self.arg(arg); + } + self + } + + fn current_dir(&mut self, dir: impl AsRef) -> &mut Self { + self.as_mut().current_dir(dir); + self + } + + fn env(&mut self, key: impl AsRef, val: impl AsRef) -> &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 invoke(&mut self) { + let status = self.status(); + if !status.success() { + panic!( + "Failed with code {}: {:?}", + status.code().unwrap(), + self.info() + ); + } + } +} + +pub(crate) struct Ext(Command); + +impl AsRef for Ext { + fn as_ref(&self) -> &Command { + &self.0 + } +} + +impl AsMut for Ext { + fn as_mut(&mut self) -> &mut Command { + &mut self.0 + } +} + +impl CommandExt for Ext {} + +impl Ext { + pub fn new(program: impl AsRef) -> Self { + Self(Command::new(program)) + } +} diff --git a/xtask/src/command/tar.rs b/xtask/src/command/tar.rs new file mode 100644 index 00000000..5ad745da --- /dev/null +++ b/xtask/src/command/tar.rs @@ -0,0 +1,29 @@ +use super::CommandExt; +use std::{ffi::OsStr, process::Command}; + +pub(crate) struct Tar(Command); + +impl AsRef for Tar { + fn as_ref(&self) -> &Command { + &self.0 + } +} + +impl AsMut for Tar { + fn as_mut(&mut self) -> &mut Command { + &mut self.0 + } +} + +impl CommandExt for Tar {} + +impl Tar { + pub fn xf(src: &impl AsRef, dst: Option>) -> Self { + let mut cmd = Command::new("tar"); + cmd.arg("xf").arg(src); + if let Some(dst) = dst { + cmd.arg("-C").arg(dst); + } + Self(cmd) + } +} diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 86136755..4b964eb0 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -6,26 +6,14 @@ extern crate clap; use clap::Parser; use clap_verbosity_flag::Verbosity; -use std::{ - ffi::{OsStr, OsString}, - fs::read_to_string, - net::Ipv4Addr, - path::Path, - process::{Command, ExitStatus}, -}; +use std::{fs::read_to_string, net::Ipv4Addr}; mod arch; -mod cargo; -mod dir; -mod download; +mod command; mod dump; -mod git; -mod make; use arch::Arch; -use cargo::Cargo; -use git::Git; -use make::Make; +use command::{Cargo, CommandExt, Ext, Git, Make}; const ALPINE_WEBSITE: &str = "https://dl-cdn.alpinelinux.org/alpine/v3.12/releases"; const ALPINE_ROOTFS_VERSION: &str = "3.12.0"; @@ -67,8 +55,8 @@ enum Commands { /// Build image Image(Arch), - /// Unit test - Test, + /// Run zCore in qemu + Qemu(Arch), } #[derive(Args)] @@ -117,7 +105,7 @@ fn main() { Commands::LibcTest(arch) => arch.libc_test(), Commands::OtherTest(arch) => arch.other_test(), Commands::Image(arch) => arch.image(), - Commands::Test => todo!(), + Commands::Qemu(arch) => arch.qemu(), } } @@ -143,12 +131,7 @@ fn git_submodule_update(init: bool) { /// 更新工具链和依赖。 fn update_all() { git_submodule_update(false); - Command::new("rustup") - .arg("update") - .status() - .unwrap() - .exit_ok() - .expect("FAILED: rustup update"); + Ext::new("rustup").arg("update").invoke(); Cargo::update().invoke(); } @@ -185,15 +168,17 @@ fn check_style() { Cargo::fmt().arg("--all").arg("--").arg("--check").invoke(); Cargo::clippy().all_features().invoke(); Cargo::doc().all_features().arg("--no-deps").invoke(); + println!("Check libos"); Cargo::clippy() .package("zcore") - .features(false, &["zircon libos"]) + .features(false, &["zircon", "libos"]) .invoke(); Cargo::clippy() .package("zcore") - .features(false, &["linux libos"]) + .features(false, &["linux", "libos"]) .invoke(); + println!("Check bare-metal"); Make::new(None) .arg("clippy") @@ -207,70 +192,3 @@ fn check_style() { .current_dir("zCore") .invoke(); } - -trait CommandExt: AsRef + AsMut { - fn arg(&mut self, s: impl AsRef) -> &mut Self { - self.as_mut().arg(s); - self - } - - fn args(&mut self, args: I) -> &mut Self - where - I: IntoIterator, - S: AsRef, - { - for arg in args { - self.arg(arg); - } - self - } - - fn current_dir(&mut self, dir: impl AsRef) -> &mut Self { - self.as_mut().current_dir(dir); - self - } - - fn env(&mut self, key: impl AsRef, val: impl AsRef) -> &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 invoke(&mut self) { - let status = self.status(); - if !status.success() { - panic!( - "Failed with code {}: {:?}", - status.code().unwrap(), - self.info() - ); - } - } -} diff --git a/zCore/build.rs b/zCore/build.rs index a61fbc3f..64dabbc5 100644 --- a/zCore/build.rs +++ b/zCore/build.rs @@ -4,11 +4,10 @@ fn main() { //println!("cargo:rerun-if-env-changed=PLATFORM"); if std::env::var("TARGET").unwrap().contains("riscv64") { - let board = std::env::var("PLATFORM").unwrap(); - let kernel_base_addr: u64 = if board.contains("d1") { + let kernel_base_addr: u64 = if std::env::var("PLATFORM").map_or(false, |p| p.contains("d1")) + { 0xffffffffc0100000 } else { - // opensbi仍旧把kernel放在0x80200000物理内存中 0xffffffff80200000 };