Skip to content

Commit d8b5ec8

Browse files
committed
feat: trying to use deno as build script.
1 parent 14a2de0 commit d8b5ec8

File tree

5 files changed

+180
-1
lines changed

5 files changed

+180
-1
lines changed

.vscode/settings.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"rust-analyzer.check.allTargets": false,
33
"rust-analyzer.check.extraArgs": [],
4-
"rust-analyzer.procMacro.enable": true
4+
"rust-analyzer.procMacro.enable": true,
5+
"deno.enable": true
56
}

byteos

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/usr/bin/env -S deno --ext=ts --allow-run --allow-read --allow-env
2+
3+
import { Command } from "https://deno.land/x/[email protected]/command/mod.ts";
4+
import { cliCommand as buildCommand } from './scripts/cli-build.ts';
5+
import { cliCommand as qemuCommand } from './scripts/cli-qemu.ts';
6+
import { logLevelEnum, archEnum } from './scripts/cli-types.ts';
7+
import { parse } from "jsr:@std/yaml";
8+
9+
const command = new Command()
10+
.name("byteos")
11+
.version("0.1.0")
12+
.description("Building tools for the byteos.")
13+
14+
.globalType("log-level", logLevelEnum)
15+
.globalOption("-l, --log-level <level:log-level>", "Set Log Level", { default: 'info' })
16+
.globalType("architecture", archEnum)
17+
.globalOption("-a, --arch [arch:architecture]", "Set the architecture", { required: true })
18+
19+
// Sub Command build
20+
.command("build", buildCommand)
21+
.command("qemu", qemuCommand);
22+
23+
// parse yaml file
24+
const data = parse(new TextDecoder("utf-8").decode(await Deno.readFile("byteos.yaml")));
25+
console.log(data);
26+
27+
try {
28+
// Parse the command.
29+
await command.parse(Deno.args);
30+
} catch (e) {
31+
console.error("Error", e);
32+
}

scripts/cli-build.ts

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import { Command, CommandOptions } from "https://deno.land/x/[email protected]/command/mod.ts";
2+
import { globalArgType } from "./cli-types.ts";
3+
4+
const targetMap: Record<string, string> = {
5+
"riscv64": 'riscv64gc-unknown-none-elf',
6+
"x86_64": 'x86_64-unknown-none',
7+
"aarch64": 'aarch64-unknown-none-softfloat',
8+
"loongarch64": 'loongarch64-unknown-none'
9+
};
10+
11+
/**
12+
* Get the path of the kernel elf file.
13+
* @param arch the architecture
14+
* @returns path to the file
15+
*/
16+
export function getKernelElf(arch: string): string {
17+
return `${Deno.cwd()}/target/${targetMap[arch]}/release/kernel`;
18+
}
19+
20+
/**
21+
* Get the path of the kernel Binary file.
22+
* @param arch the architecture
23+
* @returns path to the file
24+
*/
25+
export function getKernelBin(arch: string): string {
26+
return `${getKernelElf(arch)}.bin`;
27+
}
28+
29+
export const cargoBuild = async function(options: CommandOptions<globalArgType>) {
30+
31+
const rustflags = [
32+
"-Cforce-frame-pointers=yes",
33+
"-Clink-arg=-no-pie",
34+
"-Ztls-model=local-exec",
35+
`--cfg=root_fs="ext4_rs"`
36+
];
37+
38+
const buildProc = new Deno.Command("cargo", {
39+
args: [
40+
"build",
41+
"--release",
42+
"--target",
43+
targetMap[options.arch],
44+
],
45+
env: {
46+
ROOT_MANIFEST_DIR: Deno.cwd() + "/",
47+
MOUNT_IMG_PATH: "mount.img",
48+
HEAP_SIZE: "0x0180_0000",
49+
RUSTFLAGS: (Deno.env.get("RUSTFLAGS") || "") + ' ' + rustflags.join(' ')
50+
},
51+
});
52+
const code = await buildProc.spawn().status;
53+
if(!code.success) {
54+
console.error("Failed to build the kernel");
55+
Deno.exit(1);
56+
}
57+
58+
const objcopyProc = new Deno.Command("rust-objcopy", {
59+
args: [
60+
`--binary-architecture=${options.arch}`,
61+
getKernelElf(options.arch),
62+
"--strip-all",
63+
"-O",
64+
"binary",
65+
getKernelBin(options.arch)
66+
]
67+
});
68+
await objcopyProc.spawn().status;
69+
70+
console.log("options", options);
71+
console.log("code: ", code);
72+
}
73+
74+
export const cliCommand = new Command<globalArgType>()
75+
.description("Build Rust Kernel")
76+
.action(cargoBuild);

scripts/cli-qemu.ts

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { Command, CommandOptions } from "https://deno.land/x/[email protected]/command/mod.ts";
2+
import { globalArgType } from "./cli-types.ts";
3+
import { cargoBuild, getKernelBin, getKernelElf } from "./cli-build.ts";
4+
5+
async function runQemu(options: CommandOptions<globalArgType>) {
6+
await cargoBuild(options);
7+
8+
const qemuExecArch = {
9+
x86_64: [
10+
"-machine",
11+
"q35",
12+
"-kernel",
13+
getKernelElf(options.arch),
14+
"-cpu",
15+
"IvyBridge-v2"
16+
],
17+
riscv64: [
18+
"-machine",
19+
"virt",
20+
"-kernel",
21+
getKernelBin(options.arch)
22+
],
23+
aarch64: [
24+
"-cpu",
25+
"cortex-a72",
26+
"-machine",
27+
"virt",
28+
"-kernel",
29+
getKernelBin(options.arch)
30+
],
31+
loongarch64: [
32+
"-kernel",
33+
getKernelElf(options.arch)
34+
]
35+
};
36+
37+
const qemuCommand = new Deno.Command(`qemu-system-${options.arch}`, {
38+
args: [
39+
...qemuExecArch[options.arch],
40+
"-m",
41+
"1G",
42+
"-nographic",
43+
"-smp",
44+
"1",
45+
"-D",
46+
"qemu.log",
47+
"-d",
48+
"in_asm,int,pcall,cpu_reset,guest_errors",
49+
50+
"-drive",
51+
"file=mount.img,if=none,format=raw,id=x0",
52+
"-device",
53+
"virtio-blk-device,drive=x0"
54+
]
55+
});
56+
await qemuCommand.spawn().status;
57+
}
58+
59+
export const cliCommand = new Command<globalArgType>()
60+
.description("Run kernel in the qemu")
61+
.action(runQemu);

scripts/cli-types.ts

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { EnumType } from "https://deno.land/x/[email protected]/command/mod.ts";
2+
3+
export const logLevelEnum = new EnumType(["debug", "info", "warn", "error"]);
4+
export const archEnum = new EnumType(['x86_64', "aarch64", "riscv64", "loongarch64"]);
5+
6+
export type globalArgType = {
7+
logLevel: typeof logLevelEnum,
8+
arch: typeof archEnum
9+
};

0 commit comments

Comments
 (0)