This commit is contained in:
2026-07-20 16:34:19 -04:00
parent a87c9576fc
commit 42c96a31a2
11 changed files with 572 additions and 86 deletions
+3 -1
View File
@@ -47,7 +47,7 @@ printf 'Building Emscripten environment (qemu-wasm %s)\n' "$QEMU_WASM_COMMIT"
FLAGS="-O3 -Wno-error=unused-command-line-argument -matomics -mbulk-memory -DNDEBUG -DG_DISABLE_ASSERT -D_GNU_SOURCE -sASYNCIFY=1 -pthread -sPROXY_TO_PTHREAD=1 -sFORCE_FILESYSTEM -sALLOW_TABLE_GROWTH -sINITIAL_MEMORY=64MB -sALLOW_MEMORY_GROWTH=1 -sMAXIMUM_MEMORY=1GB -sSTACK_SIZE=1048576 -sWASM_BIGINT -sMALLOC=mimalloc -sEXPORT_ES6=1 -sASYNCIFY_IMPORTS=ffi_call_js"
if [ ! -f build/build.ninja ]; then
if [ ! -f build/build.ninja ] || ! grep -q 'block/vvfat.c' build/build.ninja; then
"$ENGINE" run --rm -v "$SRC:/qemu" "$IMAGE" bash -lc "
cd /qemu
emconfigure ./configure \\
@@ -59,6 +59,8 @@ if [ ! -f build/build.ninja ]; then
--without-default-devices \\
--with-devices-riscv32=xteink \\
--enable-system \\
--enable-qcow1 \\
--enable-vvfat \\
--with-coroutine=fiber \\
--disable-werror \\
--disable-docs \\
+7 -5
View File
@@ -1,7 +1,6 @@
import assert from 'node:assert/strict';
import { readFile } from 'node:fs/promises';
import { pathToFileURL } from 'node:url';
import { gunzipSync } from 'node:zlib';
const artifactRoot = process.argv[2];
if (!artifactRoot) {
@@ -10,22 +9,23 @@ if (!artifactRoot) {
const moduleUrl = pathToFileURL(`${artifactRoot}/qemu-system-riscv32.js`);
const rom = new Uint8Array(await readFile(`${artifactRoot}/esp32c3-rom.bin`));
const sdCard = gunzipSync(await readFile('web/assets/blank-sd.img.gz'));
const { default: createQemu } = await import(moduleUrl);
const options = {
arguments: [
'-S', '-machine', 'xteink,variant=x3', '-accel', 'tcg,tb-size=16', '-L', '/bios',
'-display', 'none', '-serial', 'null', '-nic', 'none',
'-drive', 'file=/flash.bin,if=mtd,format=raw',
'-drive', 'file=/sd.img,if=sd,format=raw',
'-drive', 'file=fat:32:rw:/sdcard,if=sd,format=raw',
],
mainScriptUrlOrBlob: moduleUrl.href,
};
options.preRun = [() => {
options.FS.mkdir('/bios');
options.FS.mkdirTree('/bios');
options.FS.mkdirTree('/var/tmp');
options.FS.mkdirTree('/sdcard/Test');
options.FS.writeFile('/bios/esp32c3-rom.bin', rom);
options.FS.writeFile('/flash.bin', new Uint8Array(16 * 1024 * 1024));
options.FS.writeFile('/sd.img', sdCard);
options.FS.writeFile('/sdcard/Test/example.txt', 'Lorem ipsum');
}];
const module = await createQemu(options);
@@ -35,6 +35,8 @@ const timer = setInterval(() => {
clearInterval(timer);
assert.equal(module._xteink_wasm_height(), 792);
assert.ok(module._xteink_wasm_framebuffer());
assert.ok(module.FS.readdir('/sdcard/Test').includes('example.txt'));
assert.equal(module.FS.readFile('/sdcard/Test/example.txt', { encoding: 'utf8' }), 'Lorem ipsum');
module._xteink_wasm_set_adc(1, 2694);
module._xteink_wasm_set_gpio(3, 0);
process.exit(0);
+5 -10
View File
@@ -1,6 +1,5 @@
import assert from 'node:assert/strict';
import { readFile } from 'node:fs/promises';
import { BUTTONS, setButton, mergeFirmware, loadEphemeralSdCard } from '../web/app.js';
import { BUTTONS, DEFAULT_SD_FILES, EXAMPLE_SD_TEXT, formatBytes, setButton, mergeFirmware } from '../web/app.js';
// Merge - app image is placed at 0x10000 in a 0xFF-erased 16 MB flash with bootloader and partitions.
const bootloader = new Uint8Array([1, 2, 3]);
@@ -15,14 +14,10 @@ assert.equal(flash[0x10000], 0xe9);
assert.equal(flash[0x20000], 0xff);
assert.throws(() => mergeFirmware(new Uint8Array([0x00]), bootloader, partitions), /0xE9/);
const compressedSd = await readFile('web/assets/blank-sd.img.gz');
const fetchSd = async () => new Response(compressedSd);
const firstSd = await loadEphemeralSdCard(import.meta.url, fetchSd);
const secondSd = await loadEphemeralSdCard(import.meta.url, fetchSd);
assert.equal(firstSd.length, 64 * 1024 * 1024);
assert.deepEqual(firstSd.slice(510, 512), new Uint8Array([0x55, 0xaa]));
firstSd[0] ^= 0xff;
assert.notEqual(firstSd[0], secondSd[0]);
assert.equal(DEFAULT_SD_FILES.get('Test/example.txt'), EXAMPLE_SD_TEXT);
assert.equal(EXAMPLE_SD_TEXT.split('Lorem ipsum').length - 1, 10);
assert.equal(formatBytes(512), '512 B');
assert.equal(formatBytes(64 * 1024 * 1024), '64.0 MiB');
const calls = [];
const module = {