Skip to content

Commit

Permalink
feat: trying to use deno as build script.
Browse files Browse the repository at this point in the history
  • Loading branch information
yfblock committed Oct 31, 2024
1 parent 14a2de0 commit d8b5ec8
Show file tree
Hide file tree
Showing 5 changed files with 180 additions and 1 deletion.
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"rust-analyzer.check.allTargets": false,
"rust-analyzer.check.extraArgs": [],
"rust-analyzer.procMacro.enable": true
"rust-analyzer.procMacro.enable": true,
"deno.enable": true
}
32 changes: 32 additions & 0 deletions byteos
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/usr/bin/env -S deno --ext=ts --allow-run --allow-read --allow-env

import { Command } from "https://deno.land/x/[email protected]/command/mod.ts";
import { cliCommand as buildCommand } from './scripts/cli-build.ts';
import { cliCommand as qemuCommand } from './scripts/cli-qemu.ts';
import { logLevelEnum, archEnum } from './scripts/cli-types.ts';
import { parse } from "jsr:@std/yaml";

const command = new Command()
.name("byteos")
.version("0.1.0")
.description("Building tools for the byteos.")

.globalType("log-level", logLevelEnum)
.globalOption("-l, --log-level <level:log-level>", "Set Log Level", { default: 'info' })
.globalType("architecture", archEnum)
.globalOption("-a, --arch [arch:architecture]", "Set the architecture", { required: true })

// Sub Command build
.command("build", buildCommand)
.command("qemu", qemuCommand);

// parse yaml file
const data = parse(new TextDecoder("utf-8").decode(await Deno.readFile("byteos.yaml")));
console.log(data);

try {
// Parse the command.
await command.parse(Deno.args);
} catch (e) {
console.error("Error", e);
}
76 changes: 76 additions & 0 deletions scripts/cli-build.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { Command, CommandOptions } from "https://deno.land/x/[email protected]/command/mod.ts";
import { globalArgType } from "./cli-types.ts";

const targetMap: Record<string, string> = {
"riscv64": 'riscv64gc-unknown-none-elf',
"x86_64": 'x86_64-unknown-none',
"aarch64": 'aarch64-unknown-none-softfloat',
"loongarch64": 'loongarch64-unknown-none'
};

/**
* Get the path of the kernel elf file.
* @param arch the architecture
* @returns path to the file
*/
export function getKernelElf(arch: string): string {
return `${Deno.cwd()}/target/${targetMap[arch]}/release/kernel`;
}

/**
* Get the path of the kernel Binary file.
* @param arch the architecture
* @returns path to the file
*/
export function getKernelBin(arch: string): string {
return `${getKernelElf(arch)}.bin`;
}

export const cargoBuild = async function(options: CommandOptions<globalArgType>) {

const rustflags = [
"-Cforce-frame-pointers=yes",
"-Clink-arg=-no-pie",
"-Ztls-model=local-exec",
`--cfg=root_fs="ext4_rs"`
];

const buildProc = new Deno.Command("cargo", {
args: [
"build",
"--release",
"--target",
targetMap[options.arch],
],
env: {
ROOT_MANIFEST_DIR: Deno.cwd() + "/",
MOUNT_IMG_PATH: "mount.img",
HEAP_SIZE: "0x0180_0000",
RUSTFLAGS: (Deno.env.get("RUSTFLAGS") || "") + ' ' + rustflags.join(' ')
},
});
const code = await buildProc.spawn().status;
if(!code.success) {
console.error("Failed to build the kernel");
Deno.exit(1);
}

const objcopyProc = new Deno.Command("rust-objcopy", {
args: [
`--binary-architecture=${options.arch}`,
getKernelElf(options.arch),
"--strip-all",
"-O",
"binary",
getKernelBin(options.arch)
]
});
await objcopyProc.spawn().status;

console.log("options", options);
console.log("code: ", code);
}

export const cliCommand = new Command<globalArgType>()
.description("Build Rust Kernel")
.action(cargoBuild);
61 changes: 61 additions & 0 deletions scripts/cli-qemu.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { Command, CommandOptions } from "https://deno.land/x/[email protected]/command/mod.ts";
import { globalArgType } from "./cli-types.ts";
import { cargoBuild, getKernelBin, getKernelElf } from "./cli-build.ts";

async function runQemu(options: CommandOptions<globalArgType>) {
await cargoBuild(options);

const qemuExecArch = {
x86_64: [
"-machine",
"q35",
"-kernel",
getKernelElf(options.arch),
"-cpu",
"IvyBridge-v2"
],
riscv64: [
"-machine",
"virt",
"-kernel",
getKernelBin(options.arch)
],
aarch64: [
"-cpu",
"cortex-a72",
"-machine",
"virt",
"-kernel",
getKernelBin(options.arch)
],
loongarch64: [
"-kernel",
getKernelElf(options.arch)
]
};

const qemuCommand = new Deno.Command(`qemu-system-${options.arch}`, {
args: [
...qemuExecArch[options.arch],
"-m",
"1G",
"-nographic",
"-smp",
"1",
"-D",
"qemu.log",
"-d",
"in_asm,int,pcall,cpu_reset,guest_errors",

"-drive",
"file=mount.img,if=none,format=raw,id=x0",
"-device",
"virtio-blk-device,drive=x0"
]
});
await qemuCommand.spawn().status;
}

export const cliCommand = new Command<globalArgType>()
.description("Run kernel in the qemu")
.action(runQemu);
9 changes: 9 additions & 0 deletions scripts/cli-types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { EnumType } from "https://deno.land/x/[email protected]/command/mod.ts";

export const logLevelEnum = new EnumType(["debug", "info", "warn", "error"]);
export const archEnum = new EnumType(['x86_64', "aarch64", "riscv64", "loongarch64"]);

export type globalArgType = {
logLevel: typeof logLevelEnum,
arch: typeof archEnum
};

0 comments on commit d8b5ec8

Please sign in to comment.