forked from rcore-os/zCore
feat(xtask): 从顶层启动 qemu
This commit is contained in:
parent
3d0186d95e
commit
9d8316b9b6
|
@ -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"
|
||||
|
|
|
@ -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<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<impl AsRef<OsStr>>) -> 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";
|
||||
|
|
|
@ -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<OsStr>) -> &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
|
||||
}
|
||||
}
|
|
@ -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<OsStr>, dst: impl AsRef<Path>) {
|
|
@ -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,
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::CommandExt;
|
||||
use super::CommandExt;
|
||||
use std::process::Command;
|
||||
|
||||
pub(crate) struct Make(Command);
|
|
@ -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<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 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<Command> for Ext {
|
||||
fn as_ref(&self) -> &Command {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl AsMut<Command> for Ext {
|
||||
fn as_mut(&mut self) -> &mut Command {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl CommandExt for Ext {}
|
||||
|
||||
impl Ext {
|
||||
pub fn new(program: impl AsRef<OsStr>) -> Self {
|
||||
Self(Command::new(program))
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
use super::CommandExt;
|
||||
use std::{ffi::OsStr, process::Command};
|
||||
|
||||
pub(crate) 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 {
|
||||
pub fn xf(src: &impl AsRef<OsStr>, dst: Option<impl AsRef<OsStr>>) -> Self {
|
||||
let mut cmd = Command::new("tar");
|
||||
cmd.arg("xf").arg(src);
|
||||
if let Some(dst) = dst {
|
||||
cmd.arg("-C").arg(dst);
|
||||
}
|
||||
Self(cmd)
|
||||
}
|
||||
}
|
|
@ -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<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 invoke(&mut self) {
|
||||
let status = self.status();
|
||||
if !status.success() {
|
||||
panic!(
|
||||
"Failed with code {}: {:?}",
|
||||
status.code().unwrap(),
|
||||
self.info()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue