Updates
This commit is contained in:
+2
-2
@@ -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
@@ -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
Reference in New Issue
Block a user