build-state.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. #!/usr/bin/env node
  2. "use strict";
  3. const path = require("path");
  4. // TODO:
  5. // - Timeout
  6. console.log("Don't forget to run `make all` before running this script");
  7. var fs = require("fs");
  8. var V86 = require("./../../../build/libv86.js").V86;
  9. const V86_ROOT = path.join(__dirname, "../../..");
  10. var OUTPUT_FILE = path.join(V86_ROOT, "images/debian-state-base.bin");
  11. process.stdin.setRawMode(true);
  12. process.stdin.resume();
  13. process.stdin.setEncoding("utf8");
  14. process.stdin.on("data", handle_key);
  15. var emulator = new V86({
  16. bios: { url: path.join(V86_ROOT, "/bios/seabios.bin") },
  17. vga_bios: { url: path.join(V86_ROOT, "/bios/vgabios.bin") },
  18. autostart: true,
  19. memory_size: 512 * 1024 * 1024,
  20. vga_memory_size: 8 * 1024 * 1024,
  21. network_relay_url: "<UNUSED>",
  22. bzimage_initrd_from_filesystem: true,
  23. cmdline: "rw init=/bin/systemd root=host9p console=ttyS0 spectre_v2=off pti=off",
  24. filesystem: {
  25. basefs: {
  26. url: path.join(V86_ROOT, "/images/debian-base-fs.json"),
  27. },
  28. baseurl: path.join(V86_ROOT, "/images/debian-9p-rootfs-flat/"),
  29. },
  30. screen_dummy: true,
  31. });
  32. console.log("Now booting, please stand by ...");
  33. var boot_start = Date.now();
  34. var serial_text = "";
  35. let booted = false;
  36. emulator.add_listener("serial0-output-byte", function(byte)
  37. {
  38. var c = String.fromCharCode(byte);
  39. process.stdout.write(c);
  40. serial_text += c;
  41. if(!booted && serial_text.endsWith("root@localhost:~# "))
  42. {
  43. console.error("\nBooted in %d", (Date.now() - boot_start) / 1000);
  44. booted = true;
  45. // sync and drop caches: Makes it safer to change the filesystem as fewer files are rendered
  46. emulator.serial0_send("sync;echo 3 >/proc/sys/vm/drop_caches\n");
  47. setTimeout(async function ()
  48. {
  49. const s = await emulator.save_state();
  50. fs.writeFile(OUTPUT_FILE, new Uint8Array(s), function(e)
  51. {
  52. if(e) throw e;
  53. console.error("Saved as " + OUTPUT_FILE);
  54. stop();
  55. });
  56. }, 10 * 1000);
  57. }
  58. });
  59. function handle_key(c)
  60. {
  61. if(c === "\u0003")
  62. {
  63. // ctrl c
  64. stop();
  65. }
  66. else
  67. {
  68. emulator.serial0_send(c);
  69. }
  70. }
  71. function stop()
  72. {
  73. emulator.stop();
  74. process.stdin.pause();
  75. }