Skip to content

Commit b203456

Browse files
committed
holy shit i am a god
1 parent d06a7b8 commit b203456

File tree

7 files changed

+103
-67
lines changed

7 files changed

+103
-67
lines changed

drivers/tty/tty_io.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1927,7 +1927,7 @@ static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp,
19271927
#endif
19281928
case MKDEV(TTYAUX_MAJOR, 1): {
19291929
struct tty_driver *console_driver = console_device(index);
1930-
1930+
pr_info("got console %p\n", console_driver);
19311931
if (console_driver) {
19321932
driver = tty_driver_kref_get(console_driver);
19331933
if (driver && filp) {
@@ -2042,8 +2042,6 @@ static struct tty_struct *tty_open_by_driver(dev_t device,
20422042
int index = -1;
20432043
int retval;
20442044

2045-
pr_info("tty_open_by_driver of %i %s\n", device, filp->f_path.dentry->d_iname);
2046-
20472045
mutex_lock(&tty_mutex);
20482046
driver = tty_lookup_driver(device, filp, &index);
20492047
if (IS_ERR(driver)) {

kernel/printk/printk.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3006,6 +3006,7 @@ struct tty_driver *console_device(int *index)
30063006

30073007
console_lock();
30083008
for_each_console(c) {
3009+
pr_info("console %s[%i] -> %p", c->name, c->index, c->device);
30093010
if (!c->device)
30103011
continue;
30113012
driver = c->device(c, index);

tools/wasm/public/index.html

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,12 @@
118118
});
119119
</script>
120120
<script type="module">
121-
import { Machine } from "./dist/index.js";
121+
import {
122+
BlockDevice,
123+
ConsoleDevice,
124+
EntropyDevice,
125+
Machine,
126+
} from "./dist/index.js";
122127

123128
const term = new Terminal({
124129
convertEol: true,
@@ -146,19 +151,36 @@
146151
document.querySelector("input[name=cmdline]").value = cmdline;
147152
document.querySelector("input[name=memory]").value = memory;
148153

154+
const stdin = new ReadableStream({
155+
start(controller) {
156+
term.onData((data) => {
157+
controller.enqueue(data);
158+
});
159+
},
160+
});
161+
162+
const stdout = new WritableStream({
163+
write(chunk) {
164+
term.write(chunk);
165+
},
166+
});
167+
const stdout2 = new WritableStream({
168+
write(chunk) {
169+
term.write(chunk);
170+
},
171+
});
172+
149173
const machine = new Machine({
150174
cmdline: cmdline.replace(/\+/g, " "),
151175
memoryMib: memory,
176+
devices: [
177+
new ConsoleDevice(stdin, stdout),
178+
new EntropyDevice(),
179+
new BlockDevice(new Uint8Array(8 * 1024 * 1024)),
180+
],
152181
});
153182

154-
machine.bootConsole.pipeTo(
155-
new WritableStream({
156-
write(chunk) {
157-
term.write(chunk);
158-
// return new Promise((r) => term.write(chunk, r));
159-
},
160-
})
161-
);
183+
machine.bootConsole.pipeTo(stdout2);
162184

163185
machine.on("halt", () => {
164186
term.write("halting...");

tools/wasm/run.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
#!/usr/bin/env -S deno run --allow-read
2-
import { Machine } from "./dist/index.js";
2+
import {
3+
BlockDevice,
4+
ConsoleDevice,
5+
EntropyDevice,
6+
Machine,
7+
} from "./dist/index.js";
38
import { parseArgs } from "jsr:@std/cli@1/parse-args";
49
import { assert } from "./src/util.ts";
510

@@ -33,9 +38,14 @@ const machine = new Machine({
3338
cmdline: args.cmdline,
3439
memoryMib: args.memory,
3540
cpus: args.cpus,
41+
devices: [
42+
new ConsoleDevice(Deno.stdin.readable, Deno.stdout.writable),
43+
new EntropyDevice(),
44+
new BlockDevice(new Uint8Array(8 * 1024 * 1024)),
45+
],
3646
});
3747

38-
machine.bootConsole.pipeTo(Deno.stdout.writable);
48+
machine.bootConsole.pipeTo(Deno.stderr.writable, { preventClose: true });
3949

4050
machine.on("halt", () => {
4151
console.log("halting...");

tools/wasm/src/index.ts

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,12 @@ import vmlinuxUrl from "./build/vmlinux.wasm";
44
import { type DeviceTreeNode, generate_devicetree } from "./devicetree.ts";
55
import init2 from "./init2.cpio";
66
import { assert, EventEmitter, get_script_path, unreachable } from "./util.ts";
7-
import {
8-
BlockDevice,
9-
ConsoleDevice,
10-
EntropyDevice,
11-
virtio_imports,
12-
VirtioDevice,
13-
} from "./virtio.ts";
7+
import { virtio_imports, VirtioDevice } from "./virtio.ts";
148
import { type Imports, type Instance, kernel_imports } from "./wasm.ts";
159
import type { InitMessage, WorkerMessage } from "./worker.ts";
1610

11+
export { BlockDevice, ConsoleDevice, EntropyDevice } from "./virtio.ts";
12+
1713
const worker_url = get_script_path(() => import("./worker.ts"), import.meta);
1814

1915
const vmlinux_response = fetch(new URL(vmlinuxUrl, import.meta.url));
@@ -45,21 +41,12 @@ export class Machine extends EventEmitter<{
4541
cmdline?: string;
4642
memoryMib?: number;
4743
cpus?: number;
44+
devices: VirtioDevice[];
4845
}) {
4946
super();
5047
this.#boot_console = new TransformStream<Uint8Array, Uint8Array>();
5148
this.#boot_console_writer = this.#boot_console.writable.getWriter();
52-
53-
this.#devices = [
54-
new EntropyDevice(),
55-
new ConsoleDevice(
56-
new ReadableStream({
57-
pull(controller) {
58-
},
59-
}),
60-
),
61-
// new BlockDevice(),
62-
];
49+
this.#devices = options.devices;
6350

6451
const PAGE_SIZE = 0x10000;
6552
const BYTES_PER_MIB = 0x100000;
@@ -118,7 +105,9 @@ export class Machine extends EventEmitter<{
118105
const vmlinux = await vmlinux_promise;
119106

120107
const boot_console_write = (message: ArrayBuffer) => {
121-
this.#boot_console_writer.write(new Uint8Array(message));
108+
this.#boot_console_writer.write(new Uint8Array(message)).catch(() => {
109+
// Ignore errors if the console is closed
110+
});
122111
};
123112
const boot_console_close = () => {
124113
this.#boot_console_writer.close();

tools/wasm/src/init2.cpio

84 Bytes
Binary file not shown.

tools/wasm/src/virtio.ts

Lines changed: 50 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -188,12 +188,12 @@ export abstract class VirtioDevice<Config extends object = object> {
188188
vqs: Virtqueue[] = [];
189189
enable(vq: number, queue: Virtqueue) {
190190
this.vqs[vq] = queue;
191-
console.log("enable", vq, queue.size);
191+
console.log("enable", this.constructor.name, vq, queue.size);
192192
}
193193
disable(vq: number) {
194194
const queue = this.vqs[vq];
195195
assert(queue);
196-
console.log("disable", vq);
196+
console.log("disable", this.constructor.name, vq);
197197
}
198198

199199
abstract notify(vq: number): void;
@@ -236,12 +236,13 @@ export class BlockDevice extends VirtioDevice<BlockDeviceConfig> {
236236
config_bytes = new Uint8Array(BlockDeviceConfig.size);
237237
config = new BlockDeviceConfig(this.config_bytes);
238238

239-
storage = new Uint8Array(1024 * 1024);
239+
#storage: Uint8Array;
240240

241-
constructor() {
241+
constructor(storage: Uint8Array) {
242242
super();
243+
this.#storage = storage;
243244
this.features |= BlockDeviceFeatures.FLUSH;
244-
this.config.capacity = BigInt(this.storage.byteLength / 512);
245+
this.config.capacity = BigInt(this.#storage.byteLength / 512);
245246
}
246247

247248
override notify(vq: number) {
@@ -273,8 +274,8 @@ export class BlockDevice extends VirtioDevice<BlockDeviceConfig> {
273274
assert(data.writable, "data must be writable when IN");
274275
const start = Number(request.sector) * 512;
275276
let end = start + data.array.byteLength;
276-
if (end >= this.storage.length) end = this.storage.length - 1;
277-
data.array.set(this.storage.subarray(start, end));
277+
if (end >= this.#storage.length) end = this.#storage.length - 1;
278+
data.array.set(this.#storage.subarray(start, end));
278279
n = end - start;
279280
status.array[0] = BlockDeviceStatus.OK;
280281
break;
@@ -284,12 +285,6 @@ export class BlockDevice extends VirtioDevice<BlockDeviceConfig> {
284285
status.array[0] = BlockDeviceStatus.UNSUPP;
285286
}
286287

287-
console.log(
288-
request.type,
289-
request.sector,
290-
status.array[0],
291-
);
292-
293288
chain.release(n);
294289
}
295290
this.trigger_interrupt("vring");
@@ -302,40 +297,61 @@ export class ConsoleDevice extends VirtioDevice<EmptyStruct> {
302297
config = new EmptyStruct(this.config_bytes);
303298

304299
#input: ReadableStream<Uint8Array>;
305-
constructor(input: ReadableStream<Uint8Array>) {
300+
#output: WritableStreamDefaultWriter<Uint8Array>;
301+
constructor(
302+
input: ReadableStream<Uint8Array>,
303+
output: WritableStream<Uint8Array>,
304+
) {
306305
super();
307306
this.#input = input;
307+
this.#output = output.getWriter();
308308
}
309309

310310
#writing: Promise<void> | null = null;
311+
async #writer(queue: Virtqueue) {
312+
const queueIter = queue[Symbol.iterator]();
313+
for await (let chunk of this.#input) {
314+
while (chunk.length > 0) {
315+
const chain = queueIter.next().value;
316+
if (!chain) {
317+
console.warn("no more descriptors, dropping console input");
318+
break;
319+
}
311320

312-
override notify(vq: number) {
313-
assert(vq === 0);
321+
const [desc, trailing] = chain;
322+
assert(desc && desc.writable, "receiver must be writable");
323+
assert(!trailing, "too many descriptors");
314324

325+
const n = Math.min(chunk.length, desc.array.byteLength);
326+
desc.array.set(chunk.subarray(0, n));
327+
chunk = chunk.subarray(n);
328+
chain.release(n);
329+
}
330+
}
331+
}
332+
333+
override async notify(vq: number) {
315334
const queue = this.vqs[vq];
316335
assert(queue);
317-
const queueIter = queue[Symbol.iterator]();
318336

319-
this.#writing ??= (async () => {
320-
for await (let chunk of this.#input) {
321-
while (chunk.length > 0) {
322-
const chain = queueIter.next().value;
323-
if (!chain) {
324-
console.warn("no more descriptors, dropping console input");
325-
break;
337+
switch (vq) {
338+
case 0:
339+
this.#writing ??= this.#writer(queue);
340+
break;
341+
case 1:
342+
for (const chain of queue) {
343+
let n = 0;
344+
for (const { array, writable } of chain) {
345+
assert(!writable, "transmitter must be readable");
346+
await this.#output.write(array);
347+
n += array.byteLength;
326348
}
327-
328-
const [desc, trailing] = chain;
329-
assert(desc && desc.writable, "receiver must be writable");
330-
assert(!trailing, "too many descriptors");
331-
332-
const n = Math.min(chunk.length, desc.array.byteLength);
333-
desc.array.set(chunk.subarray(0, n));
334-
chunk = chunk.subarray(n);
335349
chain.release(n);
336350
}
337-
}
338-
})();
351+
break;
352+
default:
353+
console.error("ConsoleDevice: unknown vq", vq);
354+
}
339355
}
340356
}
341357

0 commit comments

Comments
 (0)