This commit is contained in:
Raven Scott
2026-04-03 19:39:13 -04:00
parent 02904e7523
commit 54ea903bd4
19 changed files with 435 additions and 29 deletions
+2 -2
View File
@@ -14,7 +14,7 @@ Files in this directory are **read from disk by the seeder** (or copied into `pa
## Contents
- **`init.js`** — Kernel entry: must define `async function start(ctx)`. Boot order: **`/etc/os-release`** → **`/etc/motd`** → **`/etc/bare-os/rc`** → **`/etc/bare-os/rc.d/*`** (sorted; only names starting with a digit, plus skips dotfiles, `*~`, `README*`, `*.md`) → banner → **`readLine` / `execLine`** loop (boot snippet errors are logged, not fatal). Custom kernels may call **`ctx.registerKernelShutdownHook(fn)`** before initd disposers; see [`developer-guide/02-the-context-object.md`](../developer-guide/02-the-context-object.md).
- **`init.js`** — Kernel entry: must define `async function start(ctx)`. Boot order: **`/etc/os-release`** → **`/etc/motd`** → optional **`/etc/bare-os/rc.profile.<profile>`** (profile from **`BARE_OS_BOOT_PROFILE`** or first line of **`/etc/bare-os/profile`**) → **`/etc/bare-os/rc`** → **`/etc/bare-os/rc.d/*`** (sorted; only names starting with a digit, plus skips dotfiles, `*~`, `README*`, `*.md`) → banner → when **`BARE_OS_SKIP_REPL`**, optional one line from **`BARE_OS_ONBOOT`** or **`/etc/bare-os/onboot`** → **`readLine` / `execLine`** loop (boot snippet errors are logged, not fatal). Custom kernels may call **`ctx.registerKernelShutdownHook(fn)`** before initd disposers; use **`ctx.bareOsRuntimeCaps`** for limits and pseudo path lists ([`developer-guide/02-the-context-object.md`](../developer-guide/02-the-context-object.md)).
- **`bin/`** — **Tier-1 utilities** built by [bare-os-coreutils](../packages/bare-os-coreutils/README.md). Each file is **`runtime.js`** + optional **`lib/*-engine.js`** (**`sed`**, **`awk`**) or **`lib/man-render.js`** (**`man`**) + **`async function run(ctx, argv)`** (no ESM **`import`** in **`src/`**).
- **`share/man/man.json`** — Merged manual database for **`/bin/man`** (built by **`bare-os-coreutils`**; see [handbook ch.10](../handbook/10-manpages-and-online-help.md)).
- **`etc/os-release`** — Static OS metadata (`NAME`, `VERSION`, …).
@@ -29,7 +29,7 @@ Files in this directory are **read from disk by the seeder** (or copied into `pa
2. Run `npm run build -w bare-os-coreutils` to refresh `kernel/bin/*`.
3. Run seeder again to re-stage the drive (or use a fresh Corestore for a clean image).
Pear bundles use the **vendored** tree under `packages/bare-os-seeder/kernel/`; keep it in sync by running the same build before `pear stage`.
Pear bundles use the **vendored** tree under `packages/bare-os-seeder/kernel/`; keep it in sync by running the same build before `pear stage`. **`npm test`** runs **`scripts/verify-kernel-seeder-parity.mjs`** (after **`bare-os-coreutils`** build) so the two trees match byte-for-byte.
## See also
+87 -2
View File
@@ -2,8 +2,16 @@
* Hyperdrive-resident kernel (staged as /boot/init.js).
* Loaded by the booter with an injected ctx object (trusted replication source).
*
* Boot order: /etc/os-release → /etc/motd → /etc/bare-os/rc → /etc/bare-os/rc.d/*
* (sorted; digit-prefixed snippet names) → session banner → interactive loop.
* Boot order: /etc/os-release → /etc/motd → optional profile rc → /etc/bare-os/rc
* /etc/bare-os/rc.d/* (sorted; digit-prefixed snippet names) → session banner →
* optional oneshot onboot when BARE_OS_SKIP_REPL → interactive loop.
*
* Profile: first non-empty line of /etc/bare-os/profile, overridden by BARE_OS_BOOT_PROFILE.
* When set, runs /etc/bare-os/rc.profile.<name> if present (trusted execLine, before main rc).
*
* Non-interactive onboot: when ctx.bareOsSkipRepl, runs one line from BARE_OS_ONBOOT env
* or first non-empty, non-# line from /etc/bare-os/onboot (trusted), then readLine yields EOF.
*
* Use ctx.registerKernelShutdownHook(fn) for teardown before initd disposers.
*/
@@ -71,6 +79,80 @@ async function printMotd(ctx) {
}
}
/**
* Boot profile name: BARE_OS_BOOT_PROFILE wins over first line of /etc/bare-os/profile.
* @param {Record<string, unknown>} ctx
* @returns {Promise<string>}
*/
async function resolveBootProfileName(ctx) {
const fromEnv = ctx.env && ctx.env.BARE_OS_BOOT_PROFILE
if (fromEnv != null && String(fromEnv).trim()) return String(fromEnv).trim()
const { drive, b4a } = ctx
try {
const buf = await drive.get('/etc/bare-os/profile')
if (!buf) return ''
const line = b4a.toString(buf).split(/\r?\n/)[0] || ''
return line.trim()
} catch {
return ''
}
}
/**
* Optional trusted snippet /etc/bare-os/rc.profile.<name> (before /etc/bare-os/rc).
* @param {Record<string, unknown>} ctx
* @param {string} profileName
*/
async function runProfileRc(ctx, profileName) {
if (!profileName) return
const safe = profileName.replace(/[^a-zA-Z0-9._-]/g, '')
if (safe !== profileName) {
ctx.console.error(
'[boot] profile name contains unsupported characters; skipping rc.profile'
)
return
}
await runRcFileAt(
ctx,
`/etc/bare-os/rc.profile.${safe}`,
`rc.profile.${safe}`
)
}
/**
* When stdin is non-interactive, run a single trusted boot command (automation).
* @param {Record<string, unknown>} ctx
*/
async function runOnbootOnce(ctx) {
if (!ctx.bareOsSkipRepl) return
const { execLine, console, drive, b4a, env } = ctx
let line = ''
const fromEnv = env && env.BARE_OS_ONBOOT
if (fromEnv != null && String(fromEnv).trim()) {
line = String(fromEnv).trim()
} else {
try {
const buf = await drive.get('/etc/bare-os/onboot')
if (buf) {
for (const raw of b4a.toString(buf).split(/\r?\n/)) {
const t = raw.trim()
if (!t || t.startsWith('#')) continue
line = t
break
}
}
} catch (e) {
console.error('onboot: ' + ((e && e.message) || String(e)))
}
}
if (!line) return
try {
await execLine(line)
} catch (e) {
console.error((e && e.message) || String(e))
}
}
/**
* @param {Record<string, unknown>} ctx
* @param {string} drivePath absolute path on system drive
@@ -161,9 +243,12 @@ async function start(ctx) {
const { readLine, execLine, console } = ctx
await bootTimed(ctx, 'os-release', () => printOsRelease(ctx))
await bootTimed(ctx, 'motd', () => printMotd(ctx))
const profileName = await resolveBootProfileName(ctx)
await bootTimed(ctx, 'rc.profile', () => runProfileRc(ctx, profileName))
await bootTimed(ctx, 'rc', () => runRcFileAt(ctx, '/etc/bare-os/rc', 'rc'))
await bootTimed(ctx, 'rc.d', () => runBareOsRcDir(ctx))
await printSessionBanner(ctx)
await bootTimed(ctx, 'onboot', () => runOnbootOnce(ctx))
while (true) {
const line = await readLine('')
if (line == null) break
File diff suppressed because one or more lines are too long