buninu-linux 0.14.57 → 0.16.59

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (299) hide show
  1. package/LICENSES/linux-firmware/LICENCE.nvidia +131 -0
  2. package/LICENSES/linux-firmware/LICENSE.amdgpu +51 -0
  3. package/LICENSES/linux-firmware/LICENSE.amdisp +31 -0
  4. package/LICENSES/linux-firmware/LICENSE.i915 +39 -0
  5. package/LICENSES/linux-firmware/LICENSE.radeon +51 -0
  6. package/LICENSES/linux-firmware/LICENSE.xe +39 -0
  7. package/LICENSES/linux-firmware/WHENCE +10280 -0
  8. package/NOTICE.md +64 -46
  9. package/README.md +378 -87
  10. package/README.zh.md +2041 -0
  11. package/build-image.sh +10 -1
  12. package/build-uki.sh +3 -1
  13. package/fetch-alpine.sh +14 -0
  14. package/graphics.md +31 -0
  15. package/index.js +28 -11
  16. package/initramfs/bin/buninu-browser +4 -1
  17. package/initramfs/bin/buninu-land +1 -1
  18. package/initramfs/bin/bunterm +3 -3
  19. package/initramfs/bin/chroot +13 -0
  20. package/initramfs/bin/chvt +11 -0
  21. package/initramfs/bin/mount +4 -0
  22. package/initramfs/bin/umount +6 -0
  23. package/initramfs/bin/xdg-open +33 -0
  24. package/initramfs/buninu/CHANGELOG.md +66 -0
  25. package/initramfs/buninu/apps/bunmsh/CHANGELOG.md +4 -0
  26. package/initramfs/buninu/apps/bunmsh/package.json +1 -1
  27. package/initramfs/buninu/apps/bunmsh/src/main.js +1 -1
  28. package/initramfs/buninu/apps/jsgotty/LICENSES/MIT-jsmdcui.txt +22 -0
  29. package/initramfs/buninu/apps/jsgotty/NOTICE +5 -0
  30. package/initramfs/buninu/apps/jsgotty/README.en.md +61 -0
  31. package/initramfs/buninu/apps/jsgotty/README.md +61 -0
  32. package/initramfs/buninu/apps/jsgotty/client-modes.mjs +117 -0
  33. package/initramfs/buninu/apps/jsgotty/client.mjs +100 -10
  34. package/initramfs/buninu/apps/jsgotty/clipboard-powershell.js +18 -0
  35. package/initramfs/buninu/apps/jsgotty/clipboard.js +148 -0
  36. package/initramfs/buninu/apps/jsgotty/gotty.js +13 -0
  37. package/initramfs/buninu/apps/jsgotty/package-lock.json +2 -2
  38. package/initramfs/buninu/apps/jsgotty/package.json +1 -1
  39. package/initramfs/buninu/apps/jsgotty/static/css/index.css +14 -1
  40. package/initramfs/buninu/apps/jsgotty/static/index.html +1 -0
  41. package/initramfs/buninu/apps/jsgotty/static/js/gotty.js +187 -23
  42. package/initramfs/buninu/apps/jsgotty/static/js/kitty-keyboard.js +193 -0
  43. package/initramfs/buninu/apps/jsgotty/static/js/kitty.js +115 -7
  44. package/initramfs/buninu/apps/jsgotty/terminal-modes.js +332 -0
  45. package/initramfs/buninu/apps/jsgotty/tests/android-alt.test.js +115 -0
  46. package/initramfs/buninu/apps/jsgotty/tests/arrow-modifiers.test.js +80 -0
  47. package/initramfs/buninu/apps/jsgotty/tests/client-exit.test.mjs +45 -0
  48. package/initramfs/buninu/apps/jsgotty/tests/client-modes.test.mjs +105 -0
  49. package/initramfs/buninu/apps/jsgotty/tests/clipboard-browser.test.js +81 -0
  50. package/initramfs/buninu/apps/jsgotty/tests/clipboard.test.js +75 -0
  51. package/initramfs/buninu/apps/jsgotty/tests/kitty-keyboard-browser.test.js +53 -0
  52. package/initramfs/buninu/apps/jsgotty/tests/kitty-keyboard.test.js +102 -0
  53. package/initramfs/buninu/apps/jsgotty/tests/manual/README.md +20 -0
  54. package/initramfs/buninu/apps/jsgotty/tests/manual/keyboard-collector.cjs +55 -0
  55. package/initramfs/buninu/apps/jsgotty/tests/manual/keyboard-debug.js +74 -0
  56. package/initramfs/buninu/apps/jsgotty/tests/manual/kitty-keyboard.js +80 -0
  57. package/initramfs/buninu/apps/jsgotty/tests/manual/zoom-collector.cjs +55 -0
  58. package/initramfs/buninu/apps/jsgotty/tests/manual/zoom-debug.js +39 -0
  59. package/initramfs/buninu/apps/jsgotty/tests/manual-touch-diagnostics.js +33 -0
  60. package/initramfs/buninu/apps/jsgotty/tests/manual-touch-diagnostics.mjs +22 -0
  61. package/initramfs/buninu/apps/jsgotty/tests/nested-cli-pty.test.mjs +116 -0
  62. package/initramfs/buninu/apps/jsgotty/tests/reconnect-modes-browser.test.js +144 -0
  63. package/initramfs/buninu/apps/jsgotty/tests/reconnect-modes.md +44 -0
  64. package/initramfs/buninu/apps/jsgotty/tests/reconnect-modes.test.js +166 -0
  65. package/initramfs/buninu/apps/jsgotty/tests/touch-drag-browser.test.js +106 -0
  66. package/initramfs/buninu/apps/jsgotty/tests/wheel-browser.test.js +60 -0
  67. package/initramfs/buninu/apps/jsmdcui/CHANGELOG.md +44 -0
  68. package/initramfs/buninu/apps/jsmdcui/package.json +1 -1
  69. package/initramfs/buninu/apps/jsmdcui/src/highlight/go-regexp.js +83 -0
  70. package/initramfs/buninu/apps/jsmdcui/src/highlight/highlighter.js +49 -62
  71. package/initramfs/buninu/apps/jsmdcui/src/highlight/parser.js +8 -5
  72. package/initramfs/buninu/apps/jsmdcui/tests/go-regexp.test.js +98 -0
  73. package/initramfs/buninu/apps/jsmdcui/tests/heading-ids.test.js +21 -16
  74. package/initramfs/buninu/apps/jsmdcui/tests/highlight-regions.test.js +73 -0
  75. package/initramfs/buninu/apps/jsmdcui/tests/id-collision.test.js +32 -9
  76. package/initramfs/buninu/apps/jsmdcui/tests/markdown-behavior.mjs +9 -0
  77. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/NORMAL-HTML.md +46 -0
  78. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/README.md +85 -0
  79. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/REPORT.md +328 -0
  80. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/compare.mjs +75 -0
  81. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/go.mod +5 -0
  82. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/normal-html-report.json +619 -0
  83. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/normal-html.html +9 -0
  84. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/oracle.go +49 -0
  85. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/report.json +2174 -0
  86. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/PowerShell.txt +39 -0
  87. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/ada.txt +25 -0
  88. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/apacheconf.txt +49 -0
  89. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/arduino.txt +38 -0
  90. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/asciidoc.txt +33 -0
  91. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/asm.txt +77 -0
  92. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/ats.txt +48 -0
  93. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/awk.txt +28 -0
  94. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/b.txt +27 -0
  95. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/bat.txt +39 -0
  96. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/c.txt +34 -0
  97. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/caddyfile.txt +14 -0
  98. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/cake.txt +7 -0
  99. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/clojure.txt +18 -0
  100. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/cmake.txt +20 -0
  101. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/coffeescript.txt +32 -0
  102. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/colortest.txt +19 -0
  103. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/conky.txt +12 -0
  104. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/cpp.txt +46 -0
  105. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/crontab.txt +16 -0
  106. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/crystal.txt +28 -0
  107. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/csharp.txt +28 -0
  108. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/css.txt +19 -0
  109. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/csx.txt +7 -0
  110. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/cuda.txt +37 -0
  111. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/cython.txt +22 -0
  112. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/d.txt +52 -0
  113. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/dart.txt +27 -0
  114. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/default.txt +8 -0
  115. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/dockerfile.txt +10 -0
  116. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/dot.txt +15 -0
  117. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/elixir.txt +23 -0
  118. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/elm.txt +20 -0
  119. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/erb.txt +32 -0
  120. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/erlang.txt +23 -0
  121. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/fish.txt +20 -0
  122. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/forth.txt +17 -0
  123. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/fortran.txt +40 -0
  124. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/freebsd-kernel.txt +10 -0
  125. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/fsharp.txt +27 -0
  126. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gdscript.txt +26 -0
  127. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gemini.txt +11 -0
  128. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gentoo-ebuild.txt +28 -0
  129. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gentoo-etc-portage.txt +14 -0
  130. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/git-commit.txt +19 -0
  131. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/git-config.txt +11 -0
  132. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/git-rebase-todo.txt +10 -0
  133. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gleam.txt +44 -0
  134. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/glsl.txt +18 -0
  135. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gnuplot.txt +11 -0
  136. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/go.txt +33 -0
  137. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/godoc.txt +9 -0
  138. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/golo.txt +50 -0
  139. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gomod.txt +16 -0
  140. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/graphql.txt +20 -0
  141. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/groff.txt +18 -0
  142. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/groovy.txt +42 -0
  143. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/haml.txt +16 -0
  144. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/hare.txt +31 -0
  145. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/haskell.txt +26 -0
  146. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/hc.txt +28 -0
  147. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/html.txt +26 -0
  148. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/html4.txt +20 -0
  149. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/html5.txt +20 -0
  150. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/ini.txt +16 -0
  151. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/inputrc.txt +14 -0
  152. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/java.txt +18 -0
  153. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/javascript.txt +41 -0
  154. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/jinja2.txt +13 -0
  155. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/json.txt +21 -0
  156. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/jsonnet.txt +28 -0
  157. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/julia.txt +24 -0
  158. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/justfile.txt +26 -0
  159. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/keymap.txt +15 -0
  160. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/kickstart.txt +16 -0
  161. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/kotlin.txt +30 -0
  162. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/kvlang.txt +37 -0
  163. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/ledger.txt +13 -0
  164. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/lfe.txt +17 -0
  165. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/lilypond.txt +15 -0
  166. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/lisp.txt +17 -0
  167. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/log.txt +45 -0
  168. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/lua.txt +48 -0
  169. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/mail.txt +17 -0
  170. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/makefile.txt +25 -0
  171. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/man.txt +12 -0
  172. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/markdown.txt +21 -0
  173. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/mc.txt +11 -0
  174. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/meson.txt +29 -0
  175. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/micro.txt +25 -0
  176. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/mpdconf.txt +13 -0
  177. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/msbuild.txt +7 -0
  178. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/nanorc.txt +16 -0
  179. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/nftables.txt +22 -0
  180. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/nginx.txt +17 -0
  181. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/nim.txt +23 -0
  182. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/nix.txt +15 -0
  183. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/nu.txt +92 -0
  184. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/objc.txt +36 -0
  185. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/ocaml.txt +25 -0
  186. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/octave.txt +35 -0
  187. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/odin.txt +35 -0
  188. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/pascal.txt +22 -0
  189. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/patch.txt +13 -0
  190. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/peg.txt +16 -0
  191. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/perl.txt +27 -0
  192. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/php.txt +44 -0
  193. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/pkg-config.txt +12 -0
  194. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/po.txt +12 -0
  195. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/pony.txt +29 -0
  196. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/pov.txt +17 -0
  197. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/privoxy-action.txt +14 -0
  198. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/privoxy-config.txt +10 -0
  199. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/privoxy-filter.txt +12 -0
  200. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/proto.txt +22 -0
  201. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/prql.txt +42 -0
  202. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/puppet.txt +22 -0
  203. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/python2.txt +24 -0
  204. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/python3.txt +28 -0
  205. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/r.txt +16 -0
  206. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/raku.txt +19 -0
  207. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/reST.txt +18 -0
  208. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/renpy.txt +11 -0
  209. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/rpmspec.txt +31 -0
  210. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/ruby.txt +34 -0
  211. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/rust.txt +27 -0
  212. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/sage.txt +24 -0
  213. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/scad.txt +23 -0
  214. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/scala.txt +16 -0
  215. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/sed.txt +12 -0
  216. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/sh.txt +20 -0
  217. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/sls.txt +15 -0
  218. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/smalltalk.txt +28 -0
  219. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/solidity.txt +26 -0
  220. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/sql.txt +35 -0
  221. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/stata.txt +32 -0
  222. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/svelte.txt +10 -0
  223. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/swift.txt +53 -0
  224. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/systemd.txt +15 -0
  225. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/tcl.txt +17 -0
  226. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/terraform.txt +28 -0
  227. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/tex.txt +15 -0
  228. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/toml.txt +31 -0
  229. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/twig.txt +29 -0
  230. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/typescript.txt +32 -0
  231. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/v.txt +47 -0
  232. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/vala.txt +22 -0
  233. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/verilog.txt +37 -0
  234. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/vhdl.txt +37 -0
  235. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/vi.txt +17 -0
  236. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/vue.txt +29 -0
  237. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/xml.txt +14 -0
  238. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/xresources.txt +14 -0
  239. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/yaml.txt +19 -0
  240. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/yum.txt +12 -0
  241. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/zig.txt +24 -0
  242. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/zscript.txt +31 -0
  243. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/zsh.txt +21 -0
  244. package/initramfs/buninu/package.json +1 -1
  245. package/initramfs/init.js +19 -3
  246. package/initramfs/lib/bunterm/clipboard.js +14 -0
  247. package/initramfs/lib/bunterm/commands.js +37 -0
  248. package/initramfs/lib/bunterm/fps.js +38 -0
  249. package/initramfs/lib/bunterm/images.js +14 -6
  250. package/initramfs/lib/bunterm/input.js +58 -15
  251. package/initramfs/lib/bunterm/keyboard.js +62 -0
  252. package/initramfs/lib/bunterm/keycodes.js +104 -0
  253. package/initramfs/lib/bunterm/kitty-keyboard.cjs +195 -0
  254. package/initramfs/lib/bunterm/raw-protocol.js +111 -0
  255. package/initramfs/lib/bunterm/renderer.js +116 -28
  256. package/initramfs/lib/bunterm/selection.js +60 -0
  257. package/initramfs/lib/bunterm/terminal.js +157 -12
  258. package/initramfs/lib/bunterm/vt-menu.js +181 -0
  259. package/initramfs/lib/bunterm/vt.js +27 -1
  260. package/initramfs/lib/canvas.js +99 -0
  261. package/initramfs/lib/chvt.js +31 -0
  262. package/initramfs/lib/fbdev.js +32 -8
  263. package/initramfs/lib/gpu.js +77 -0
  264. package/initramfs/lib/mapped-frame.js +28 -0
  265. package/initramfs/lib/raw-image.js +71 -0
  266. package/initramfs/lib/xdg-open.js +42 -0
  267. package/initramfs/usr/share/doc/buninu-linux/bunterm.md +85 -11
  268. package/initramfs/usr/share/doc/buninu-linux/chvt.md +34 -0
  269. package/initramfs/usr/share/doc/buninu-linux/xdg-open.md +43 -0
  270. package/package.json +1 -1
  271. package/scripts/arch.js +7 -5
  272. package/scripts/arch.sh +5 -5
  273. package/scripts/build.js +16 -3
  274. package/scripts/fetch-gpu.js +105 -0
  275. package/scripts/fetch.js +11 -1
  276. package/scripts/gpu-firmware.json +22 -0
  277. package/scripts/modules.js +4 -1
  278. package/scripts/npm-packages.md +18 -17
  279. package/test/bunterm-fps.test.js +17 -0
  280. package/test/bunterm-image-bytes.test.js +15 -0
  281. package/test/bunterm-keyboard.test.js +116 -0
  282. package/test/bunterm-mapped-lifetime.test.js +147 -0
  283. package/test/bunterm-next-vt.test.js +9 -0
  284. package/test/bunterm-raw-protocol.test.js +39 -0
  285. package/test/bunterm-renderer.test.js +167 -0
  286. package/test/bunterm-selection.test.js +38 -0
  287. package/test/bunterm-vt-menu.test.js +178 -0
  288. package/test/chroot-bind.test.js +40 -2
  289. package/test/chvt.test.js +46 -0
  290. package/test/fbdev-sync.test.js +42 -0
  291. package/test/fetch-npm.test.js +2 -2
  292. package/test/gpu.test.js +155 -0
  293. package/test/image-size.test.js +17 -0
  294. package/test/manual-bunterm-image-paths.js +31 -0
  295. package/test/mount-libc-lifetime.test.js +50 -0
  296. package/test/no-gpu.test.js +43 -0
  297. package/test/readme-cli.test.js +29 -0
  298. package/test/stage-npm.test.js +11 -4
  299. package/test/xdg-open.test.js +55 -0
package/README.zh.md ADDED
@@ -0,0 +1,2041 @@
1
+ # Buninu Linux
2
+ - Buninu Linux 是以 Bun 作為 PID 1、搭配 Buninu 使用者空間的 Linux 發行版。
3
+ - 整個使用者空間都以 Bun 為基礎
4
+ - 透過未簽章的 UEFI UKI(統一核心映像)開機,即 vda.img 中單一的 `.EFI` 檔案,內含以下元件
5
+ * Alpine 預先編譯的核心
6
+ * Alpine 預先編譯的 systemd EFI stub
7
+ * initramfs JavaScript 元件:
8
+ * `/init.js`、Buninu 使用者空間及其他模組
9
+ * initramfs 原生元件:
10
+ * 官方 `bun-linux-x64-musl`(或 `bun-linux-aarch64-musl`)及其依賴
11
+ + ld-musl-x86_64.so.1 (ld-musl-aarch64.so.1)
12
+ + libc.musl-x86_64.so.1 (libc.musl-aarch64.so.1; 刻意保留的副本)
13
+ + libgcc_s.so.1
14
+ + libstdc++.so.6
15
+ - 可在真實 x86-64 UEFI 硬體開機;QEMU 系統測試同時支援 x86_64
16
+ 與 aarch64 客體。
17
+ - 核心將 `bun` 作為 PID 1 執行
18
+ * init 通常負責的一切工作——掛載檔案系統、載入模組、設定網路、回收子行程
19
+ * 都透過 JavaScript 的 `bun:ffi` 完成
20
+ * 不使用 BusyBox,也沒有 C 啟動程式。
21
+
22
+ - 首頁:<https://buninu.org>
23
+ - 原始碼:[github.com/jjtseng93/buninu-linux](https://github.com/jjtseng93/buninu-linux)
24
+ - Buninu 使用者空間原始碼:[github.com/jjtseng93/buninu](https://github.com/jjtseng93/buninu)
25
+ + **BUNinu Is Not Unix** 🐮
26
+ + **幫你牛** 🐂 ・ **Bunに入魂** 🔥
27
+ - <img src="https://raw.githubusercontent.com/jjtseng93/buninu/main/icon.png" width="256">
28
+
29
+ ---
30
+
31
+ - [English](README.md)
32
+ - [目錄](#目錄)
33
+ - 終端機文件:`bun x buninu-linux --readme`(英文),
34
+ `bun x buninu-linux --readme-zh` 或 `--docs`(繁體中文)。
35
+ - .
36
+ - 仍處於早期階段
37
+ - [影片在此](https://www.reddit.com/r/bun/comments/1wkpraj/buninu_linux_a_distro_with_bun_as_pid_1):已透過 `--real` 在真實 x86-64 UEFI 硬體成功開機:
38
+ * Bun 進入互動式 REPL
39
+ * `start` 啟動 Buninu 使用者空間 shell
40
+ * `cfg.disk` 搭配 shell 的 `mount` 掛載本機磁碟
41
+ * `cfg.net` 載入常見有線網卡與 Android USB 網路共享驅動,並自動嘗試 DHCP 設定
42
+ * `cfg.sound` 載入所有已打包的 ALSA 音效模組
43
+ * 已成功測試透過 RNDIS 使用 Android 手機 USB 網路共享,讓 Buninu Linux 經由手機連上網際網路
44
+ * DHCP 租約到期或需要重新取得網路設定時,執行 `dhclient usb0`(換成實際介面名稱)。仍可使用 `ip` 手動設定。
45
+ * 內附的 `jmi` 編輯器、jsmdcui App 執行環境及本機 JavaScript 執行也可運作。
46
+ * 透過核心 VT 或 jsmdcui 進行多工
47
+ + 請見[多工模式](#多工模式)
48
+ * 圖形終端機 `bunterm` 在 framebuffer 上繪製中日韓文字、彩色 emoji 與 Kitty 圖片;請見[顯示圖片](#顯示圖片)
49
+ + 也支援滑鼠點擊、滾輪及游標繪製
50
+ + 簡易瀏覽器可運作:原生 buninu-browser,或 chroot Debian 中的 casty
51
+ + 可播放有聲音的 YouTube(實驗性);請見[播放有聲音的影片](#實驗性有聲影片播放)
52
+ + 內建瀏覽器請見 [Buninu Browser](#內建瀏覽器的早期實驗支援),可選的 chroot 設定請見 [Debian 與 Chromium 搭配 casty](#在隔離根目錄使用瀏覽器前端)
53
+ * [從 Bun 建立 C 編譯器](initramfs/usr/lib/bootstrap/README.md):
54
+ + 編號腳本產生 musl 標頭檔與 CRT,
55
+ + 建置 TinyCC 並下載後續建置至 GCC 4.7 所需的原始碼,從 `bun /usr/lib/bootstrap/1.prepare-rootfs.js` 開始。
56
+
57
+ ---
58
+
59
+ - [第一節](#第一節問候範例)的 hello-world EFI 應用程式是 UKI 所取代的起點
60
+ - 它仍可建置,也是確認磁碟映像與韌體路徑是否能運作的最快方式。
61
+
62
+ ## 快速開始
63
+
64
+ > [!IMPORTANT]
65
+ > 本節建置用於真實 x86-64 UEFI 硬體的映像檔。若要改用
66
+ > `qemu-system` 建置及測試 x86_64 或 aarch64 客體,請見
67
+ > [在桌面系統建置及測試虛擬機](#在桌面系統建置及測試虛擬機)。
68
+
69
+ 你可以在 Android 手機建置映像檔,但以下 `--real` 映像是用來
70
+ 啟動 x86-64 UEFI 電腦,並不是把 Buninu Linux 安裝到手機上。
71
+
72
+ - 本教學會建置可開機的 `buninu-linux-<version>.img`
73
+ - 下載與建置預設使用 JS 工具,需要主機的 Bun,不需要原生
74
+ 建置工具鏈或 Docker;不必只為了建置而進入 PRoot。
75
+
76
+ ### 步驟
77
+
78
+ - 先安裝 bun:
79
+ * Android:在 Termux 執行以下命令:
80
+
81
+ ```sh
82
+ pkg update && pkg upgrade
83
+ pkg i npm
84
+ npm i -g bun
85
+ ```
86
+
87
+ * 其他平台:依照官方教學:<https://bun.com>
88
+ - 安裝 Bun 並確認在 `PATH` 內後,選擇下列任一建置方法。
89
+ * 可用 `bun --version` 檢查
90
+ - 不要設定 `BUNINU_JS_TOOLS`(或設為 `1`);`0`、`off`
91
+ 或 `false` 會改用[舊版 shell 建置](#舊版建置工具)。
92
+
93
+ #### 直接透過套件建置
94
+
95
+ 進入要存放完成映像檔的目錄,直接執行已發布的套件。不需要用
96
+ `apt install`/`apk add` 安裝建置工具:
97
+
98
+ ```sh
99
+ mkdir -p buninu-build
100
+ cd buninu-build
101
+ bun x buninu-linux --version
102
+ bun x buninu-linux -fb --real --export
103
+ ```
104
+
105
+ `--export` 會把完成的 `vda.img` 從 bunx
106
+ 套件目錄複製到執行命令時所在的目錄,命名為
107
+ `buninu-linux-<version>.img`。寫入 USB 隨身碟
108
+ 時,請使用命令輸出的完整匯出檔名。
109
+
110
+ #### 或從原始碼建置
111
+
112
+ 準備好 Git 與 Bun 後:
113
+
114
+ ```sh
115
+ git clone https://github.com/jjtseng93/buninu-linux.git buninu-linux
116
+ cd buninu-linux
117
+ bun ./index.js -fb --real --export
118
+ ```
119
+
120
+ 這會下載已鎖定的 Alpine/Bun/npm 輸入、選取真機模組、建置 `vda.img`,
121
+ 並匯出 `buninu-linux-<version>.img`。
122
+
123
+ 若要較小的映像檔,可在任一建置命令加入 `--no-gpu`:
124
+
125
+ ```sh
126
+ bun x buninu-linux -fb --real --no-gpu --export
127
+ # 從原始碼目錄建置:
128
+ bun ./index.js -fb --real --no-gpu --export
129
+ ```
130
+
131
+ x86-64 `--real` 參考建置使用 `--no-gpu`
132
+ 時產生 **128 MiB** 映像,預設包含 GPU 模組與韌體
133
+ 則為 **320 MiB**。此選項省略可選的 GPU 套件內容,
134
+ 保留 framebuffer/bunterm 軟體顯示路徑。映像大小依
135
+ 打包內容計算,後續版本可能改變。
136
+
137
+ #### 寫入映像檔到隨身碟
138
+
139
+ 建議使用 **Ventoy**:先透過 Windows 或
140
+ Linux 電腦在隨身碟安裝一次,再從 Android、
141
+ Linux、macOS 或 Windows 複製映像檔進去。後續
142
+ 建置只需將新的 `.img` 複製到同一隨身碟,不必每次重新燒錄
143
+ 或格式化。可保留多個映像,從 Ventoy 開機選單選擇。
144
+
145
+ 在 Android 上,先讓檔案管理員能存取匯出的映像。執行
146
+ `termux-setup-storage` 並接受儲存權限提示,
147
+ 或在 Android 應用程式設定中允許 Termux
148
+ 管理所有檔案(若有此選項)。從匯出映像所在目錄將檔案複製到
149
+ Download:
150
+
151
+ ```sh
152
+ termux-setup-storage
153
+ cp buninu-linux-*.img /sdcard/Download/
154
+ ```
155
+
156
+ 請使用完整匯出的 `.img`(未使用 `--export` 時
157
+ 則為 `vda.img`),而不是其中的 FAT 分割區。請將下方範例
158
+ 檔名換成建置輸出的實際名稱。
159
+
160
+ **Android/Termux:複製到已準備好的 Ventoy 隨身碟。**
161
+ 一般未 root 的 Android/Termux 無法透過 `dd` 直接
162
+ 存取 USB 區塊裝置,PRoot 也不會賦予此權限。一個方法是先
163
+ [透過 Windows 或 Linux 電腦在隨身碟安裝 Ventoy](https://www.ventoy.net/en/doc_start.html),
164
+ 再用 USB OTG 連接 Android,以檔案管理員將
165
+ `.img` 複製到 Ventoy 資料分割區。安全退出後,讓目標電腦從
166
+ 隨身碟開機,在 Ventoy 選單選取映像。Ventoy 支援
167
+ `.img`,不必解壓縮或改名成 `.iso`。
168
+
169
+ ---
170
+
171
+ 首次安裝 Ventoy 會清除所選隨身碟。之後複製映像
172
+ 檔進去不必重新格式化。若要保留 Ventoy 安裝,
173
+ 請勿對該隨身碟使用 `dd` 或 Rufus。
174
+
175
+ Ventoy 與直接寫入映像兩種方式擇一使用。若已使用 Ventoy,
176
+ 略過下方 Linux/macOS/Windows 直接寫入
177
+ 方法,繼續[從隨身碟開機](#從隨身碟開機)。
178
+
179
+ **Linux:使用 `dd` 直接寫入。** 先用 `lsblk`
180
+ 辨認隨身碟並卸載其已掛載的分割區。下方 `/dev/sdX`
181
+ 指整顆磁碟,不是 `/dev/sdX1` 之類的分割區。
182
+ 此操作會覆寫目標磁碟、分割表及既有檔案,請仔細確認裝置。
183
+
184
+ ```sh
185
+ sudo dd if='buninu-linux-<version>.img' of=/dev/sdX bs=4M conv=fsync status=progress
186
+ ```
187
+
188
+ **macOS:使用 `dd` 直接寫入。** 用 `diskutil list`
189
+ 辨認隨身碟,將下方 `N` 換成實際磁碟編號。同樣會覆寫
190
+ 整顆磁碟。請使用 macOS 的 `bs=4m` 寫法;複製
191
+ 時按 `Ctrl-T` 可查看進度。
192
+
193
+ ```sh
194
+ diskutil list
195
+ diskutil unmountDisk /dev/diskN
196
+ sudo dd if='buninu-linux-<version>.img' of=/dev/rdiskN bs=4m
197
+ sync
198
+ diskutil eject /dev/diskN
199
+ ```
200
+
201
+ **Windows:使用 [Rufus](https://rufus.ie/) 寫入。**
202
+ Rufus 除了 ISO,也支援原始 `.img` 磁碟映像(見
203
+ [官方常見問題](https://github.com/pbatard/rufus/wiki/FAQ#openbsd))。
204
+ 選取正確的 USB 裝置,以匯出的 `.img` 作為開機映像並開始寫入。若出現提示,使用
205
+ DD/原始映像模式。此操作會覆寫所選隨身碟,不必轉成 `.iso`。
206
+
207
+ #### 從隨身碟開機
208
+
209
+ 以 x86-64 UEFI 模式從該隨身碟開機。UKI 未簽章,
210
+ 除非自行簽署,否則請停用 Secure Boot。真機成功開機後,
211
+ 本機螢幕與 USB 鍵盤會呈現如下結尾的歡迎訊息:
212
+
213
+ ```text
214
+ Welcome to Buninu Linux!
215
+ Bun 1.4.2 is now PID 1
216
+ Type start() to run buninu --local
217
+ Configuration getters: cfg.all, cfg.disk, cfg.net, cfg.power, cfg.sound, cfg.gpu
218
+
219
+ bun-repl>
220
+ ```
221
+
222
+ 若看不到歡迎訊息,可能只是後續核心訊息將它從同一主控台捲走。
223
+ 在空的 REPL 提示按 Enter;空白或只有空格的行會
224
+ 再次印出歡迎訊息及目前的 `cfg.*` getter 清單。
225
+
226
+ 只載入需要的子系統,再進入 Buninu shell:
227
+
228
+ ```js
229
+ cfg.net // 有線網卡與 Android USB 網路共享驅動
230
+ cfg.disk // SATA/NVMe/USB 儲存驅動及偵測到的區塊裝置
231
+ cfg.power // 電池、交流電源、按鈕與溫度驅動
232
+ cfg.sound // 所有已打包 ALSA 音效模組及偵測到的音效裝置
233
+ start()
234
+ ```
235
+
236
+ `start()` 開啟 Buninu shell 後,執行:
237
+
238
+ ```sh
239
+ bunterm 2
240
+ ```
241
+
242
+ 這會在虛擬主控台 2 開啟圖形終端機並切換過去。它支援中文、
243
+ emoji 及瀏覽器終端圖形。用 `Ctrl+Alt+F1`
244
+ 回到原始主控台,`Ctrl+Alt+F2`
245
+ 回到此終端機。
246
+
247
+ 執行 `poweroff` 可同步
248
+ 資料後關機。修改 initramfs 後,用 `bun ./index.js -b --real --export`
249
+ 重建映像;`-h` 列出所有旗標。
250
+
251
+ ### 在桌面系統建置及測試虛擬機
252
+
253
+ > [!IMPORTANT]
254
+ > 本節只涵蓋用 `qemu-system` 建置與執行的客體。若要建置
255
+ > 真實 x86-64 UEFI 硬體使用的映像,請依照上方[快速開始](#快速開始)
256
+ > 並使用 `-fb --real --export`。
257
+
258
+ 本節命令假設你已依[從原始碼建置](#或從原始碼建置)
259
+ 複製原始碼並進入目錄,不必先執行該節的 `--real`
260
+ 建置。Bun 必須在 `PATH` 中;依
261
+ 下方步驟安裝 QEMU。
262
+
263
+ 同一個 `index.js` 可在 Mac 或 Linux 主機的 QEMU 中建置及啟動 Buninu
264
+ Linux。`--arch` 選取客體架構:
265
+
266
+ | 主機 | `--arch x86_64`(預設) | `--arch aarch64`(別名 `arm64`) |
267
+ | --- | --- | --- |
268
+ | Apple Silicon Mac | q35,模擬(TCG) | `virt`,硬體加速(Hypervisor.framework) |
269
+ | Intel Mac | q35,硬體加速(Hypervisor.framework) | `virt`,模擬(TCG) |
270
+ | x86-64 Linux | 可使用 `/dev/kvm` 時,q35 硬體加速(KVM) | `virt`,模擬(TCG) |
271
+ | arm64 Linux | q35,模擬(TCG) | 可使用 `/dev/kvm` 時,`virt` 硬體加速(KVM) |
272
+ | Android Termux | q35,模擬(TCG) | `virt`,可使用 `/dev/kvm` 時採用 KVM,否則為 TCG |
273
+
274
+ `run-qemu.sh` 自行選取加速器;`ACCEL=tcg` 強制使用模擬。
275
+
276
+ #### macOS
277
+
278
+ 預設 JS 工具直接透過主機 Bun 在 macOS 建置,不需要 Docker。
279
+ 若用 `BUNINU_JS_TOOLS=0` 停用,`index.js` 會在由
280
+ [`Dockerfile`](Dockerfile) 建立、以 Debian 為
281
+ 基礎的 `oven/bun:1.4.2` 容器內執行 shell 下載與建置階段,並綁定掛載
282
+ 原始碼目錄。首次使用時建立容器映像,以 Dockerfile 雜湊作為標籤。在此 shell
283
+ 工具模式下,只有執行階段直接使用 Mac 本身:
284
+
285
+ ```sh
286
+ # -f/-b 使用主機 Bun;-r 使用 QEMU 及其 UEFI 韌體
287
+ brew install qemu
288
+
289
+ # Apple Silicon:Hypervisor.framework 加速 aarch64 客體
290
+ bun ./index.js -fbr --arch arm64
291
+
292
+ # x86_64 客體也可運作,採用模擬
293
+ bun ./index.js -fbr
294
+ ```
295
+
296
+ `run-qemu.sh` 的第一行開機訊息列出選取的客體、機器、加速器
297
+ 及韌體。單獨使用 `-r` 會啟動 `vda.img` 上次建置的架構;
298
+ `-br --arch arm64` 是 aarch64 修改後建置及開機的循環。若要
299
+ 在 aarch64 客體的 QEMU 視窗執行 `bunterm`,
300
+ 請見[此架構的差異](#六十四位元安謀架構的差異)。
301
+
302
+ #### amd64 Linux
303
+
304
+ 在 Debian 或 Ubuntu 上,預設 JS 建置需要主機 Bun,
305
+ 不需要原生建置工具鏈。當使用者能開啟 `/dev/kvm` 時,QEMU 會為
306
+ x86_64 客體使用 KVM。安裝 QEMU 及其韌體後即可建置開機:
307
+
308
+ ```sh
309
+ sudo apt install qemu-system-x86 ovmf
310
+ bun ./index.js -fbr
311
+ ```
312
+
313
+ 若要執行 aarch64 客體,另安裝 `qemu-system-arm`
314
+ 與 `qemu-efi-aarch64`。預設 JS 建置不需要交叉 binutils。
315
+ 可選的[舊版 shell 建置](#舊版建置工具)則需要原生工具鏈(aarch64
316
+ 包含 `binutils-aarch64-linux-gnu`),或設定
317
+ `BUNINU_JS_TOOLS=0` 並傳入 `--docker`,改用建置容器。
318
+
319
+ #### 六十四位元安謀架構的差異
320
+
321
+ * 映像位於同一 GPT 磁碟的 `vda/EFI/BOOT/BOOTAA64.EFI`,以 Alpine
322
+ aarch64 套件及 `bun-linux-aarch64-musl` 建置。
323
+ * 序列主控台是 `ttyAMA0`(QEMU `virt` 的 PL011),而非 `ttyS0`。
324
+ * `--real` 僅適用 x86_64,其模組集針對個人電腦硬體。
325
+ * QEMU 的 `virt` 機器沒有顯示器或 PS/2 裝置,因此 `bunterm`
326
+ 預設沒有繪製目標;序列 REPL 與 Buninu shell 的運作方式與 x86_64
327
+ 相同。若要執行 `bunterm`,請用 `--linux-lts` 建置,並給 QEMU
328
+ `ramfb` 顯示裝置及 virtio 輸入裝置。在 Mac 上,`-display cocoa`
329
+ 會開啟視窗:
330
+
331
+ ```sh
332
+ bun ./index.js -fbr --arch arm64 --linux-lts -- \
333
+ -device ramfb -device virtio-keyboard-pci -device virtio-mouse-pci -display cocoa
334
+ ```
335
+
336
+ 建置完成後,可以不重建(也不使用 Docker)而再次開機。
337
+ `--linux-lts` 屬於建置選項,因此使用 `-r` 時省略:
338
+
339
+ ```sh
340
+ bun ./index.js -r --arch arm64 -- \
341
+ -device ramfb -device virtio-keyboard-pci -device virtio-mouse-pci -display cocoa
342
+ ```
343
+
344
+ 在序列 REPL 執行 `start()`,再執行 `bunterm 2`,
345
+ 便會在 QEMU 視窗的 VT 2 開啟 bunterm,並返回序列
346
+ shell;請在視窗內輸入。單獨使用 `bunterm` 也預設採用 VT
347
+ 2,保留 VT 1 設定硬體。指定非目前使用中的 VT 時會以分離模式啟動(見[多個虛擬主控台](#多個虛擬主控台))。韌體將 ramfb 設為 800×600,
348
+ `init.js` 載入 `simpledrm`,讓它成為 `/dev/fb0`(見
349
+ [graphics.md](graphics.md#trying-it))。
350
+ * `--export` 寫出 `buninu-linux-<version>-aarch64.img`。
351
+ * 核心啟動前,Homebrew 的 aarch64 EDK2 會印出幾行
352
+ `Error: Image at … start failed`(其驅動對應的硬體不存在於
353
+ `virt`)及 `ConvertPages: failed to find range …`
354
+ (無法將 UKI 放在 stub 偏好的位址,因此重新定位)。兩者皆無害,
355
+ 之後會出現 `BdsDxe: starting Boot0001` 並繼續開機。
356
+
357
+ #### 在容器中測試主機建置流程
358
+
359
+ `test/host/host-test.sh` 可在任何有 Docker 的機器
360
+ 檢查 Linux 主機路徑:它啟動指定 CPU 的全新 `oven/bun:1.4.2`
361
+ 容器,內含上述建置套件及 QEMU,複製目前原始碼已提交的 `HEAD`,
362
+ 以 Bun 和預設 JS 工具建置兩種客體(不巢狀使用 `--docker`),依序開機並用
363
+ `test/host/boot-test.exp` 操作序列主控台:
364
+
365
+ ```sh
366
+ test/host/host-test.sh arm64 # Linux arm64 主機(Apple Silicon 上原生執行)
367
+ test/host/host-test.sh amd64 # Linux x86-64 主機(在該平台模擬執行)
368
+ ```
369
+
370
+ 每個步驟——REPL、`start()`、`uname`、eth0、PID 1、掛載
371
+ tmpfs、客體下載及 `poweroff`——都等待預期輸出,最後以 `### PASS`
372
+ 和結束狀態 0,或 `### FAIL` 和 1 結束。未提交的專案變更不會被測試,請先提交。
373
+ `GUESTS=aarch64` 限制客體架構,`BUILD_FLAGS=--linux-lts`
374
+ 加入建置旗標,`downloads/` 以唯讀方式作為下載快取。Docker
375
+ Desktop 不提供 `/dev/kvm`,因此兩種客體皆使用 TCG;Linux
376
+ 主機有 KVM 時腳本會傳入,對應架構的客體以 `accel=kvm` 開機。在
377
+ macOS,同一份 `boot-test.exp` 也能驅動本機開機:先
378
+ 執行 `bun ./index.js -b --arch arm64`,再執行
379
+ `expect test/host/boot-test.exp "$PWD" aarch64`。
380
+
381
+ `ALPINE_MIRROR` 可將 Alpine CDN 換成鏡像站,例如
382
+ `ALPINE_MIRROR=https://mirrors.edge.kernel.org/alpine`;
383
+ 每次下載仍會依鎖定的 SHA-256 驗證。
384
+
385
+ ## 使用作業系統
386
+
387
+ ### 基本設定
388
+
389
+ 主要目標是真實硬體。除非自行簽署 UKI,否則請停用
390
+ Secure Boot 後從隨身碟開機。實體螢幕與 USB 鍵盤
391
+ 提供 `bun-repl>` 提示。
392
+
393
+ 只載入需要的硬體子系統:
394
+
395
+ ```js
396
+ cfg.net
397
+ cfg.disk
398
+ cfg.power
399
+ cfg.sound
400
+ ```
401
+
402
+ `cfg.net` 載入已打包的有線網路及 Android
403
+ USB 網路共享驅動,印出偵測到的介面及 MAC 位址,並自動
404
+ 嘗試 DHCP 設定。成功後不必另下 DHCP 命令。
405
+
406
+ 租約到期或需要重新取得網路設定時,用 `start()` 進入
407
+ Buninu shell,再執行 `dhclient usb0`
408
+ (將 `usb0` 換成介面名稱)。它只設定介面一次
409
+ 便退出,不會自動續租。
410
+
411
+ 若要手動設定固定 IP,使用:
412
+
413
+ ```sh
414
+ ip link set eth0 up
415
+ ip addr add 192.168.1.50/24 dev eth0
416
+ ip route add default via 192.168.1.1
417
+ ```
418
+
419
+ 真機映像以 `1.1.1.1` 和 `8.8.8.8` 初始化
420
+ `/etc/resolv.conf`;若網路需要其他 DNS,請自行更換。
421
+ `cfg.disk` 載入常見 SATA/PATA/SCSI、NVMe
422
+ /VMD 及 USB 儲存裝置驅動,讓偵測到的磁碟與分割區出現在
423
+ `/dev`。`cfg.sound` 無條件載入映像中所有音效模組,再
424
+ 列出產生的 `/dev/snd` 裝置;載入前不做硬體探測。若只想查看
425
+ 檔案系統而不掛載:
426
+
427
+ ```sh
428
+ mount -fv /dev/sda1 /mnt
429
+ ```
430
+
431
+ 執行 `poweroff` 可同步資料後關機。
432
+
433
+ ### 使用終端機
434
+
435
+ `bunterm` 是 Linux framebuffer 上的圖形終端機,不必啟動
436
+ X11 或 Wayland 即可顯示中日韓文字、彩色 emoji 與 Kitty
437
+ 圖形。在真機映像中,於 `bun-repl>` 提示用 `start()` 進入
438
+ shell,再執行:
439
+
440
+ ```sh
441
+ bunterm # 在最後工作階段之後開新 VT;首次為 tty2
442
+ bunterm 3 -s 16 # 另一個工作階段,字體 16 px(預設:13)
443
+ # 或在未使用的 VT 啟動指定應用程式:
444
+ bunterm 4 -e jsmdcui --allow-url README.md
445
+ ```
446
+
447
+ 若要在新的瀏覽器終端開啟網址或既有的本機檔案:
448
+
449
+ ```sh
450
+ xdg-open https://buninu.org
451
+ xdg-open "./page with spaces.html"
452
+ ```
453
+
454
+ `xdg-open` 在新的 VT 執行 `bunterm -e buninu-browser URL`。
455
+ HTTP/HTTPS 與 `about:` URL 直接開啟;本機路徑與 `file://` URL
456
+ 會解析為既有的一般檔案,並編碼為絕對檔案 URL。不支援目錄與其他 URL
457
+ 協定。用 `xdg-open --help` 查看用法。
458
+
459
+ 用 `Ctrl+Alt+F1` 回到初始主控台,`Ctrl+Alt+F2` 回到 VT 2,
460
+ 或用 `Alt+Left`/`Alt+Right` 切換 VT。在 shell 執行
461
+ `chvt 1`、`chvt 2` 也有相同效果。切換保留執行中的工作階段;離開某工作
462
+ 階段的 shell 或應用程式則結束該 bunterm。
463
+
464
+ 點擊螢幕最左上角的 **2×2 像素** 開啟選單:
465
+
466
+ | 控制項 | 用途 |
467
+ | --- | --- |
468
+ | 🔤 字體 − / + | 調整目前工作階段的文字及終端格數;字體大小置中顯示於按鈕之間。 |
469
+ | 📋 複製 | 用滑鼠左鍵拖曳選取終端文字,再複製到共用的 xclip 剪貼簿。只有應用程式未啟用滑鼠回報時才能選取。 |
470
+ | 📥 貼上 | 從 xclip 貼上。啟用 bracketed paste 的應用程式會收到其分隔序列,其餘收到純文字。 |
471
+ | 命令輸入 | 點擊淺色輸入框或按 Tab,輸入 `font 16`、`font +`、`font -`、`copy`、`paste`、`vt 2` 或 `help`,再按 Enter。這些是 bunterm 本身的命令。 |
472
+ | VT 列表 | 切換到既有 bunterm 或初始 tty。目前 VT 標記為 `(current)`。 |
473
+ | + 新增 bunterm | 在列表最大編號的下一個 tty 啟動 bunterm,沿用目前字體大小。 |
474
+
475
+ 按 Esc 關閉選單。字體調整只保留於目前工作階段。應用程式
476
+ 未要求滑鼠事件時,滾輪可捲動終端歷史。`--no-mouse` 停用
477
+ 滑鼠輸入與選單;`--no-clipboard`
478
+ 同時停用選單剪貼簿操作及 OSC 52。應用
479
+ 程式間共享文字請見[剪貼簿](#剪貼簿)。
480
+
481
+ **Kitty keyboard:**應用程式可協商旗標
482
+ **1、2、8**,使用與 jsgotty 相同的編碼器,區分 Ctrl
483
+ /Alt/Shift/Super 組合,並要求按下、重複及放開事件。
484
+ 不需要啟動旗標。一般應用程式仍使用主控台轉譯後的輸入;應用程式停用 Kitty
485
+ 或 bunterm 退出時會還原原始鍵盤模式。VT 切換快捷鍵仍保留。
486
+ Kitty 模式尚未實作 dead key/Compose 序列。完整
487
+ 選項與鍵盤細節見 `bunterm --help`。
488
+
489
+ Casty 是 [buninu-browser](#內建瀏覽器的早期實驗支援) 和 [buninu-land](#內建合成器的早期實驗支援) 的預設終端前端,負責將畫面顯示在 bunterm 裡,並轉送鍵盤與滑鼠輸入。使用方式請見連結指向的後續章節。
490
+
491
+ 點擊 bunterm 選單標題右側的 FPS 按鈕,可開啟/關閉終端右上角的青藍色計數器。它每秒取樣一次,統計實際呈現的新 Kitty 圖片幀(例如 Casty/Land 輸出),不計滑鼠與選單重畫。靜態圖片與純文字工作階段顯示 0 FPS。設定僅作用於目前 bunterm,預設關閉。
492
+
493
+ 若要查看 Casty 目前的畫面傳輸路徑,按 `Ctrl-E`,輸入 `kitty`,
494
+ 再按 Enter。在 Land 中則點擊 **@** 開啟命令列。
495
+ 例如 `Kitty: file · format=bgra` 表示透過共用檔案傳送原始像素;
496
+ `rgba` 也是原始像素,PNG/JPEG 則表示已編碼圖片。支援的本機兩端
497
+ 會自動協商 raw,不需要額外啟動旗標。
498
+ bunterm 的 FPS 計數器統計實際呈現的圖片,不是客戶端本身的渲染 FPS。
499
+
500
+ ### 使用命令殼層
501
+
502
+ bunmsh 是 Buninu 內附、受 mksh 啟發且無外部依賴的 shell。
503
+ 主要功能如下:
504
+
505
+ - 以 `Bun.*` 開頭的行作為 JavaScript 執行;印出回傳值並自動
506
+ 等待 Promise。可用 `Bun.e;` 或 `Bun.e,` 執行任意
507
+ JavaScript。
508
+ - 輕量的工作目錄分頁可保留多個工作目錄。在 bunmsh 中,
509
+ `Ctrl-T` 建立或向右循環分頁,`Alt-T` 則向左循環。
510
+ * 其他實用命令:`tab n`、`tab c`(Alt-C)
511
+ - shell 變數與 JavaScript 透過 `$.` 共用即時變數表,`Bun.sha`
512
+ 可跨命令及工作目錄分頁保留 JavaScript 值。
513
+ - 互動模式提供歷史儲存、匯入 Bash/Fish 歷史、
514
+ 補全與幽靈文字建議。
515
+ - `serve [directory]` 啟動可瀏覽的 HTTP 檔案
516
+ 伺服器。搭配 Android USB 網路共享,可簡單地在 Buninu
517
+ Linux 與連接的手機之間傳輸檔案。
518
+ - 提供跨平台內建命令及 PATH 備援命令。
519
+ - `Ctrl-U` 移除並保存游標前的文字;在行
520
+ 首再次按下可還原。`Ctrl-K` 獨立處理游標後
521
+ 的文字,在行尾時可切換還原。
522
+ - 未加引號的路徑模式使用 `Bun.Glob`,如同
523
+ 傳統 shell,會跟隨路徑中間的目錄符號連結。這對
524
+ sysfs 很重要,因為 class 項目通常是連結。例如:
525
+
526
+ ```sh
527
+ ls /sys/class/net/*/device
528
+ ```
529
+
530
+ 若要方便閱讀的行程概覽,執行:
531
+
532
+ ```sh
533
+ pspac
534
+
535
+ # 核心執行緒顯示為 [name];濾除後只看使用者空間
536
+ pspac | grep -v '\[[a-z]'
537
+ ```
538
+
539
+ `pspac` 顯示實際的 `PID COMMAND` 行程表,並以
540
+ micro 的 Monokai 配色將各命令列作為 shell 語法
541
+ 上色。開頭的目錄以暗色顯示,凸顯程式名稱。`pspa` 則以純文字顯示同
542
+ 一份表格。
543
+
544
+ 完整語法、互動操作、內建命令及目前相容性細節,請見
545
+ [bunmsh 儲存庫](https://github.com/jjtseng93/bunmsh)。
546
+
547
+ ### 編輯器快速開始
548
+
549
+ 內附的 `jmi` 終端編輯器不需要網路連線:
550
+
551
+ ```sh
552
+ jmi hlw.js
553
+ ```
554
+
555
+ - 建議使用 `jmi` 的 `cmc-tc` 色彩主題
556
+ - 設定方式:
557
+ * 按 `Ctrl-E`
558
+ * 輸入 `theme `(包含結尾空白)
559
+ * 按 `Tab`,使用上下方向鍵選取
560
+ * 按 `Enter`。
561
+
562
+ - 輸入並儲存(Ctrl-S)以下內容:
563
+
564
+ ```js
565
+ console.log("Hello world from real hardware");
566
+ ```
567
+
568
+ 用 `Ctrl-Q` 離開編輯器後,在本機執行:
569
+
570
+ ```sh
571
+ bun hlw.js
572
+ ```
573
+
574
+ 若特定終端機無法辨識 `Enter`,可嘗試 `Ctrl-J` 或
575
+ `Ctrl-M`。
576
+
577
+ #### jsmdcui
578
+ - `jsmdcui` 是同一個編輯器,但預設會把 Markdown 檔案當作互動式 App 執行
579
+ - 請小心,不要執行陌生人提供的 Markdown 檔案
580
+ * 否則它可以在你的電腦上執行任何命令
581
+ - `jsmdcui --cdp-maze` 執行會自行解題的迷宮遊戲
582
+ * 先執行 `bunterm 2` 才能顯示其中的 emoji
583
+
584
+ ### 多工模式
585
+
586
+ #### 多個虛擬主控台
587
+
588
+ 在每個 Linux 虛擬主控台分別執行 `bunterm`。數字
589
+ 位置參數是對應裝置的簡寫,因此 `bunterm 2` 等同
590
+ `bunterm /dev/tty2`。省略參數時,在最後一個已知工作階段之後開啟新的 VT(首次為 tty2):
591
+
592
+ ```sh
593
+ bunterm 2
594
+ bunterm 3 -s 13
595
+ ```
596
+
597
+ 指定的 VT 不是目前使用中的 VT 時,`bunterm` 會以分離工作
598
+ 階段在該處啟動,切換顯示過去,並立即將控制權交回呼叫它的 shell。
599
+ 用 `Ctrl+Alt+F1` 至 `Ctrl+Alt+F12` 切換
600
+ VT,或用 `Alt+Left`、`Alt+Right` 移到上一個或下
601
+ 一個 VT。每個 VT 保有自己的終端工作階段;非使用中的 bunterm
602
+ 仍會處理 PTY,但停止繪製,直到其 VT 再次啟用。每個 VT 只能由
603
+ 一個 bunterm 控制。若已被使用,錯誤訊息會指出其 PID 並建議
604
+ 其他 VT 編號。
605
+
606
+ #### 編輯器的窗格與終端分頁
607
+
608
+ `jmi` 與 jsmdcui 可同時開啟編輯器及終端工作階段。按
609
+ `Ctrl-E`,輸入 `term` 後按 `Enter`,便會在終端窗格開啟
610
+ 預設 Buninu shell。`term COMMAND` 則啟動指定命令。在
611
+ 同一 `Ctrl-E` 命令提示使用 `vsplit`、`hsplit`
612
+ 或 `tab`,可建立其他編輯窗格或分頁;各命令皆可選擇傳入檔名。在編輯窗
613
+ 格中,`Ctrl-T` 是開啟空白新分頁的直接快捷鍵。
614
+
615
+ ##### 窗格與分頁操作
616
+
617
+ | 輸入 | 結果 |
618
+ | --- | --- |
619
+ | 點擊窗格 | 聚焦該編輯器或終端窗格。 |
620
+ | 在編輯窗格按 `Ctrl-T` | 開啟空白新分頁。 |
621
+ | 按一次 `Ctrl-W` | 從編輯器或終端窗格移到目前分頁的下一個窗格。 |
622
+ | `Alt-T` | 移到下一個分頁。 |
623
+ | **快速按兩次 `Ctrl-W`** | **重要的離開操作:**如同 `Alt-T` 移到下一個分頁,必要時建立編輯器分頁。詳細說明見下文。 |
624
+ | 在終端窗格按 `Esc` | 關閉該終端窗格,回到先前的編輯器緩衝區 |
625
+ | 在編輯窗格按 `Ctrl-Q` 或 `Alt-Q` | 關閉目前編輯器介面。 |
626
+
627
+ **為何此離開操作很重要:**終端窗格必須將幾乎所有組合鍵原樣轉送給
628
+ 其中執行的 shell 或應用程式。因此
629
+ `Ctrl-W` 是 jsmdcui 攔截的多工
630
+ 離開鍵,讓你能離開目前終端而不終止裡面的工作。按一次
631
+ 移到目前分頁的下一個窗格;快速按兩次移到下一個分頁。
632
+
633
+ 雙按在全是終端的工作區特別重要。目前分頁是
634
+ 最右側,而且所有既有分頁都只有終端窗格時,
635
+ 會建立新編輯器分頁,而非繞回第一個終端分頁。
636
+ 其他情況都執行正常的下一分頁循環。只有確實
637
+ 要關閉目前終端窗格時才使用 `Esc`。
638
+
639
+ ### 顯示圖片
640
+
641
+ Linux 文字主控台不能繪製圖片,因此先啟動 framebuffer
642
+ 圖形終端機 `bunterm`,再於其中執行圖片命令。請在另一個虛擬
643
+ 主控台啟動,讓 tty1 保留 `bun-repl>` 提示供硬體設定
644
+ 使用(用 `Ctrl+Alt+F1` 回去):
645
+
646
+ ```sh
647
+ # 在 VT 2 啟動圖形終端機(等同 bunterm /dev/tty2)
648
+ bunterm 2
649
+
650
+ # 用 Kitty 圖形協議顯示圖片(jsgotty --viu)
651
+ showimg /buninu/icon.png
652
+
653
+ # 用 glow 顯示 README.md,再顯示 icon.png
654
+ buninu-help
655
+
656
+ # 在 Markdown 檢視中就地顯示圖片
657
+ # 先執行 cfg.net 才能顯示該 GitHub 圖片
658
+ jsmdcui --allow-url README.md
659
+
660
+ # bunterm 支援滑鼠;--no-mouse 不操作 /dev/input
661
+ # (使用 VT 3,因為 VT 2 已有上面啟動的 bunterm)
662
+ bunterm 3 -e jsmdcui --allow-url README.md
663
+ ```
664
+
665
+ `bunterm` 用 Skia(CanvasKit)繪製並理解 Kitty
666
+ 圖形協議,因此 `showimg`、`jsmdcui`、`kitten icat`、
667
+ `timg` 等使用此協議的程式都能顯示圖片,也能呈現中日韓文字與彩色
668
+ emoji。顯示圖片後游標會移到圖片下方,圖片也會隨文字捲動。啟動的程式
669
+ 結束後,主控台回到文字模式。選項見 `bunterm --help`;
670
+ [graphics.md](graphics.md) 說明其實作方式。映像需要
671
+ 支援 framebuffer 的核心:請用 `--linux-lts` 或
672
+ `--real` 建置(預設 `linux-virt` 只將它建成模組,而映像未打包該
673
+ 模組)。aarch64 客體還需要 QEMU 顯示
674
+ 裝置,請見[此架構的差異](#六十四位元安謀架構的差異)。
675
+
676
+ ### 剪貼簿
677
+
678
+ `bunterm` 透過 OSC 52 支援複製貼上,讓 `casty`、
679
+ `jsmdcui` 等程式可使用剪貼簿。bunterm 本身不保存內容,每次複製貼上都
680
+ 交給 Buninu 的 `xclip -selection clipboard`。
681
+ 目前剪貼簿是記憶體磁碟中的 `$HOME/.xclip.clipboard`
682
+ 檔案,所以所有 bunterm 工作階段共用,重開機後會消失。應用程式
683
+ 未啟用滑鼠回報時,才可左鍵拖曳選字。點擊左上角 **2×2 像素** 可開啟
684
+ **複製/貼上**、**字體 − / +**、VT 列表及本機命令欄位
685
+ (`font 16`、`copy`、`paste`、`vt 2`、`help`)。
686
+ 應用程式要求時,貼上會使用 bracketed paste。
687
+ `bunterm --no-clipboard` 同時停用 OSC 52 與選單剪貼簿操作。
688
+
689
+ 選單與 Kitty keyboard 支援請見[使用終端機](#使用終端機)。
690
+
691
+ 在 `buninu-browser` 中,HTTPS 或 localhost 網頁的 Copy 按鈕可在
692
+ 使用者點擊或按鍵後,透過 `navigator.clipboard.writeText()` 寫入文字。
693
+ 瀏覽器控制端優先使用 `xclip -selection clipboard`,
694
+ 因此複製的文字會進入 bunterm 與 jsmdcui 使用的同一剪貼簿。
695
+ 若沒有可用的剪貼簿提供者,操作會回報失敗。
696
+ 這與在 Casty 中選取文字後使用複製快捷鍵是不同的功能。
697
+
698
+ 若要輸入中文,在 chroot 外的 bunterm 執行拼音輸入法
699
+ [jspinyin](https://www.npmjs.com/package/@drxiaozhi/jspinyin),
700
+ 讓它使用 Buninu 的 `xclip`:
701
+
702
+ ```sh
703
+ jspinyin
704
+ ```
705
+
706
+ - jspinyin → casty:在 jspinyin 按 `Ctrl-C` 複製結果框,再於 casty
707
+ 按 `Ctrl-V` 或輸入 `Ctrl-E paste`,便會透過 OSC 52 貼上。
708
+ - casty → jsmdcui/jspinyin:在 casty 按 `Alt-C` 透過 OSC
709
+ 52 複製選取內容,再於 jsmdcui 或 jspinyin 按 `Ctrl-V` 貼上,因為
710
+ jsmdcui 預設優先讀取 `xclip`。
711
+
712
+ jspinyin 也提供**清除/還原**按鈕。清除會先保存目前結果,
713
+ 再清空結果框;還原則把保存的文字追加到結果尾端。
714
+ 還原後仍保留緩衝內容,因此可重複點擊以追加同一段文字。
715
+ 候選字選取與其他操作,請見輸入面板內的說明連結。
716
+
717
+ ### 實驗性有聲影片播放
718
+
719
+ 已內建的 [jspulse](https://github.com/jjtseng93/jspulse)
720
+ 是為 Bun 撰寫、相容 PulseAudio 的音效伺服器。它在 chroot
721
+ 外的 Buninu 原生執行,透過 ALSA 播放。Debian chroot 內
722
+ `casty` 等基於 Chromium 的程式透過 `127.0.0.1`
723
+ 連線,因為 chroot 共用 Buninu 網路。多個程式可以同時播放。
724
+
725
+ 此處假設已完成
726
+ [Debian 與 Chromium 搭配 casty](#在隔離根目錄使用瀏覽器前端)的 Debian chroot
727
+ 及 `casty` 設定,chroot shell 位於 tty2。
728
+ `bun x` 需要網路,請見[基本設定](#基本設定)。
729
+
730
+ 1. **載入音效驅動。** 按 `Ctrl+Alt+F1` 回到 tty1 的
731
+ `bun-repl>` 提示並執行:
732
+
733
+ ```js
734
+ cfg.sound
735
+ ```
736
+
737
+ 2. **開啟原生 Buninu 終端。** 仍在 tty1 時,用
738
+ `start()` 進入 Buninu shell,再從該 shell 開啟另一
739
+ 個虛擬主控台(見[多工模式](#多工模式))。接下來兩個步驟請在那裡執行,*不是
740
+ *在 chroot 內:
741
+
742
+ ```js
743
+ start()
744
+ ```
745
+
746
+ ```sh
747
+ bunterm 3
748
+ ```
749
+
750
+ 3. **辨認音效卡、設定音量並測試播放。** 先列出
751
+ ALSA 音效卡及混音控制項:
752
+
753
+ ```sh
754
+ jspulse --audio-info
755
+ ```
756
+
757
+ 內建喇叭或插在電腦音源孔的耳機,請選**主機板類比音效**卡。若列出
758
+ card 0 **HDA Intel HDMI**、card 1
759
+ **HDA Intel PCH**、card 2 **HDA NVIDIA**,先試
760
+ **card 1(HDA Intel PCH)**。`Speaker Playback`、
761
+ `Headphone Playback`、`PCM Playback` 或
762
+ `Master Playback` 等控制項是辨認這類輸出的線索。
763
+
764
+ 若要從接在該 GPU 的螢幕或電視發聲,則選
765
+ **HDMI/DisplayPort** 音效卡。Intel
766
+ HDMI 與 NVIDIA 音效通常不會輸出到電腦的類比耳機孔。USB
767
+ 耳機或 USB 音效卡應使用自己的 USB 音效卡。
768
+
769
+ 音效卡編號依機器而異;請把下方 `1` 換成
770
+ 連接所需輸出的音效卡,再用測試音確認。
771
+
772
+ ```sh
773
+ jspulse --card 1 --volume 50
774
+ jspulse --card 1 --play
775
+ ```
776
+
777
+ 設定支援的播放音量也會解除對應開關的靜音。
778
+ HDMI 卡可能沒有硬體播放音量控制,此時略過
779
+ `--volume`,改調連接的螢幕/電視音量。
780
+ 這本身不代表 HDMI 無法播放。測試音會檢查選取的
781
+ 輸出;請視需要調整音量。
782
+
783
+ 4. **在同一音效卡啟動音效伺服器。** 它持續在前景
784
+ 執行,因此保留此終端;`Ctrl+C` 可停止:
785
+
786
+ ```sh
787
+ jspulse --alsa --card 1
788
+
789
+ # 或在背景啟動
790
+ jspulse --alsa --card 1 &
791
+ ```
792
+
793
+ 5. **啟動有音效的 casty。** 按 `Ctrl+Alt+F2` 回到 chroot
794
+ shell,將 PulseAudio 客戶端指向 jspulse,再啟動 casty:
795
+
796
+ ```sh
797
+ export PULSE_SERVER=127.0.0.1
798
+ cd ~/casty/bin
799
+ bun casty.js https://www.youtube.com
800
+ ```
801
+
802
+ 另一種方式是內建 `buninu-browser`,它直接在
803
+ chroot 外的原生 Buninu `bunterm` 執行,
804
+ 使用同一個執行中的 jspulse 伺服器。它仍在早期實驗
805
+ 階段,但可播放個別影片,例如:
806
+
807
+ ```sh
808
+ buninu-browser https://youtu.be/jf-pn0a-Twk
809
+ ```
810
+
811
+ 播放仍可能失敗或不穩定;這不代表完整相容
812
+ YouTube。
813
+
814
+ 若沒有聲音,檢查步驟 4 的終端是否有錯誤,並確認在啟動 casty
815
+ 的同一個 shell 匯出了 `PULSE_SERVER`。
816
+
817
+ ### 資料與持久保存
818
+
819
+ Buninu Linux 從記憶體中的 initramfs
820
+ 執行。預設家目錄(`/buninu`)、系統設定及工作
821
+ 階段中安裝的套件,除非存到已掛載的磁碟,否則重開機後會
822
+ 消失。`/tmp` 也是暫存空間。開機映像不會自動將變更
823
+ 寫回自身,僅在 `/mnt` 建立目錄也不會讓資料永久保存。
824
+
825
+ 若要保留檔案,在初始 `bun-repl>` 提示載入儲存驅動,再進入
826
+ shell:
827
+
828
+ ```js
829
+ cfg.disk
830
+ start()
831
+ ```
832
+
833
+ 掛載既有資料分割區(將 `/dev/sda1` 換成實際分割區),
834
+ 再將檔案存入或複製進去:
835
+
836
+ ```sh
837
+ mount /dev/sda1 /mnt/data --mkdir
838
+ mkdir -p /mnt/data/work
839
+ cp /buninu/notes.md /mnt/data/work/notes.md
840
+ cd /mnt/data/work
841
+ ```
842
+
843
+ 複製範例假設你已建立 `/buninu/notes.md`。
844
+ 分割區掛載時寫入 `/mnt/data` 的檔案
845
+ 會留在磁碟上。重開機後再次掛載同一分割區便可
846
+ 存取。這不會自動還原家目錄、已安裝套件或系統設定。
847
+
848
+ 拔除磁碟前,關閉正在使用它的程式、離開其中的
849
+ 目錄,再成功卸載:
850
+
851
+ ```sh
852
+ cd /
853
+ umount /mnt/data
854
+ ```
855
+
856
+ ## 內建命令
857
+
858
+ | 命令 | 功能 | 手冊 |
859
+ | --- | --- | --- |
860
+ | `buninu-linux-help` | 顯示 `/usr/share/doc/buninu-linux/README.md` 中的本份 buninu-linux README | `buninu-linux-help` |
861
+ | `buninu-browser` | 早期實驗性的 JavaScript/WASM 瀏覽器,搭配內附 casty 終端前端;尚不能取代通用瀏覽器 | `buninu-browser --help` |
862
+ | `buninu-land` | 實驗性的軟體渲染 Wayland 合成器,搭配內附 casty 終端前端 | `buninu-land --help` |
863
+ | `jspulse` | 相容 PulseAudio 的音效伺服器與 ALSA 混音控制;在 Buninu Linux 使用 `--alsa` | `jspulse --help` |
864
+ | `jspinyin` | 透過系統 jsmdcui 以 TUI 模式開啟的中文拼音輸入面板;不是全系統輸入法 | — |
865
+ | `mount` | `mount(2)`,支援類型偵測、`-o` 解析、`LABEL=`/`UUID=`、bind/move/remount,並載入所需檔案系統及磁碟模組 | `mount --help` → `/usr/share/doc/buninu-linux/mount.md` |
866
+ | `umount` | `umount2(2)`,支援 `-l`、`-f`、`-R` | `umount --help` |
867
+ | `ip` | 透過 `SIOC*` ioctl 與 `/proc/net` 提供 iproute2 語法:`link`、`addr`、`route`、`neigh` | `ip --help` |
868
+ | `dhclient` | 到期或需要時重新取得 DHCPv4 設定(`dhclient usb0`)後退出,也支援釋放租約 | `dhclient --help` |
869
+ | `ping` | 透過 Bun FFI 傳送 IPv4 ICMP/IPv6 ICMPv6 echo;支援次數、間隔、逾時、總期限、資料大小、TTL 及來源選擇 | `ping --help` |
870
+ | `ps` | 從 `/proc` 取得可組合的行程欄位,也匯出快照及單列格式化函式供其他命令使用 | `ps --help` |
871
+ | `top` | 定期更新由 `ps` 提供的行程快照與各列 | `top --help` |
872
+ | `xdg-open` | 在新的 bunterm VT 用 buninu-browser 開啟 HTTP/HTTPS、`about:` 或既有本機檔案 | `xdg-open --help` |
873
+ | `chvt` | 切換 Linux VT(`chvt 1`/`chvt 2`),包含離開與返回 bunterm | `chvt --help` |
874
+ | `poweroff` | 同步待寫入資料,透過 Linux reboot 系統呼叫關機 | `poweroff --help` |
875
+ | `reboot` | 同步待寫入資料,透過共用的 Linux reboot 邏輯重新啟動 | `reboot --help` |
876
+ | `tar` | 透過 `Bun.Archive` 建立、解開或列出 tar 封存檔,支援 gzip 與 zstd 壓縮 | `tar --help` |
877
+ | `gzip`、`gunzip`、`zcat` | 壓縮或解壓縮 gzip 檔案,包含解壓縮到標準輸出 | `gzip --help` |
878
+ | `unzip` | 列出或解開 ZIP 封存檔,或用 `-p` 將其中項目寫到標準輸出 | `unzip --help` |
879
+ | `truncate` | 調整檔案大小,包含稀疏檔案 | `truncate --help` |
880
+ | `dd` | 在檔案間複製區塊,支援偏移、大小限制與稀疏輸出 | `dd --help` |
881
+ | `mkfs.fat` | 在磁碟映像內格式化 FAT32 檔案系統 | `mkfs.fat --help` |
882
+ | `mmd`、`mcopy`、`mdir` | 不掛載即可在 FAT 映像建立目錄、複製檔案及列出內容;使用 `-i IMAGE` 與 `::/path` | — |
883
+ | `parted` | 在磁碟映像建立及檢查 GPT 分割區;支援腳本模式子集 | `parted --help` |
884
+ | `stripansi` | 移除標準輸入、`-` 或一至多個檔案的 ANSI 跳脫序列,並串接結果 | — |
885
+ | `chroot` | 以 `chroot(2)` 進入另一個根目錄,自動掛載 `/proc`、`/sys`、`/dev`、`/dev/pts`、`/run`、`/tmp` 及 `/etc/resolv.conf`;支援 `-b HOST[:GUEST]`、`--shared-tmp`,退出時自動清理 | `chroot --help` |
886
+ | `bunterm` | framebuffer 圖形終端:以 Skia(CanvasKit)顯示中日韓文字、彩色 emoji、無縫框線與 Kitty 圖片,支援滑鼠及滾輪歷史捲動(`--no-mouse` 可停用);透過 Bun 內建 PTY 使用 xterm.js 模擬核心 | `bunterm --help` |
887
+
888
+ 除了 `bun`(及指向它的 `sh`/`node`),`/bin`
889
+ 也包含上述命令,以 Bun 腳本或內附套件的輕量啟動器實作。
890
+
891
+ Debian/Alpine rootfs 與 Chromium
892
+ 範例,請見[可選的根目錄切換與原生程式](#可選的根目錄切換與原生程式)。
893
+
894
+ `ping -c 4 127.0.0.1` 檢查 IPv4 連線;`ping -6 -c 4 ::1`
895
+ 檢查 IPv6。`ping -c 10 -i 0.2 -W 1 HOST` 調整次數、
896
+ 間隔及回覆逾時。此命令直接使用 ICMP socket,必要時退回 raw socket。
897
+ 透過共用 libc 載入器支援 Linux glibc/musl 與原生 Android
898
+ bionic;`BUNINU_LIBC` 仍可明確覆寫選擇。執行
899
+ `bun test test/ping.test.js test/libc.test.js`
900
+ 可與已安裝的系統 ping 對照。權限需求與支援旗標見 `ping --help`。
901
+
902
+ ### 內建瀏覽器的早期實驗支援
903
+
904
+ `buninu-browser` 仍在早期階段。網站可能顯示
905
+ 不正確、無法載入或播放媒體,尚不能取代通用瀏覽器。請在
906
+ `bunterm`(或其他支援 Kitty 圖形的終端)內執行。
907
+ 瀏覽器與 casty 已內附,這些命令不會從 npm 安裝它們。
908
+
909
+ ```sh
910
+ # 開啟 Buninu 網站(需要網路)
911
+ buninu-browser buninu.org
912
+
913
+ # 開啟瀏覽器內建音效測試頁
914
+ buninu-browser about:audio
915
+ ```
916
+
917
+ 若要音效輸出,先在 PID 1 REPL 用 `cfg.sound` 載入
918
+ 音效驅動,再於另一個終端執行 `jspulse --alsa`,或用 `jspulse --alsa &` 在背景執行。在瀏覽器終端中:
919
+
920
+ ```sh
921
+ buninu-browser about:audio
922
+ ```
923
+
924
+ 若要瀏覽使用自簽 HTTPS 憑證的可信任測試網站,可只針對
925
+ 該次執行停用憑證驗證:
926
+
927
+ ```sh
928
+ env NODE_TLS_REJECT_UNAUTHORIZED=0 buninu-browser https://localhost:8443
929
+ ```
930
+
931
+ 這也會停用該行程及繼承環境的子行程對其他請求的憑證驗證。
932
+ 請勿將它全域匯出;未設定此覆寫時,
933
+ 憑證驗證仍保持啟用。
934
+
935
+ ### 內建合成器的早期實驗支援
936
+
937
+ 在 `bunterm`(或其他支援 Kitty 圖形的終端)內執行
938
+ `buninu-land`,即可開啟 Wayland 桌面。合成器與 Casty 已內附,
939
+ 啟動時不需從 npm 下載。
940
+
941
+ ```sh
942
+ buninu-land
943
+ ```
944
+
945
+ 啟動器啟用 Casty 的 `--no-shortcuts`:頁面按鍵傳給 Land 與其
946
+ 客戶端,不觸發 Casty 快捷鍵。若要退出前端,點擊網址列左側的
947
+ **@**,輸入 `q` 後按 Enter。點擊網址本身
948
+ 則進入編輯;網址列顯示實際的 Wayland socket 路徑。
949
+
950
+ 在 bunterm 或支援 Kitty keyboard 的 jsgotty 中使用內附 Casty,
951
+ 會自動轉送 Super 組合鍵及放開事件:
952
+
953
+ | 快捷鍵 | 動作 |
954
+ | --- | --- |
955
+ | Super+方向鍵 | 聚焦該方向的視窗 |
956
+ | Super+W/Super+Q | 要求關閉目前聚焦視窗 |
957
+ | Super+F | 切換全螢幕 |
958
+ | Super+T | 切換浮動/平鋪 |
959
+ | Super+Alt+F | 在 Land 的單一輸出切換最大化 |
960
+ | Super+Shift+方向鍵 | 與該方向的平鋪視窗交換 |
961
+ | Alt+Tab/Alt+Shift+Tab | 向前/向後循環切換視窗 |
962
+ | Super+1–9 | 切換工作區 |
963
+ | Super+Shift+1–9 | 將聚焦視窗移到該工作區並跟隨過去 |
964
+ | Super+-/Super+= | 水平縮小/放大;加 Shift 改為垂直 |
965
+
966
+ 調整尺寸預設每次 100 邏輯像素,加 Alt 為 25,加 Ctrl 為 300。
967
+ 平鋪視窗調整的是分割比例。這些是已實作的視窗操作,
968
+ 不是完整 Omarchy 桌面。傳統終端無法可靠傳送 Super;
969
+ Ctrl+Alt 組合現在直接傳給客戶端,不再作為替代快捷鍵。
970
+
971
+ **客戶端 GPU 加速:**先在初始 REPL 執行 `cfg.gpu`,再開啟
972
+ bunterm(見[可選的客戶端圖形加速](#可選的客戶端圖形加速))。
973
+ 接著在 bunterm 執行 Land,指定要向客戶端宣告的 GPU render 節點:
974
+
975
+ ```sh
976
+ buninu-land -- --gpu=/dev/dri/renderD128
977
+ ```
978
+
979
+ 請將範例節點換成實際裝置;編號可能隨開機改變。
980
+ 客戶端環境仍須具備可運作的 Mesa 驅動,並能存取同一個
981
+ render 節點。chroot 內的客戶端也必須能存取 Land 的 Wayland socket。
982
+ 此預設組合啟用線性 DMA-BUF 匯入、延後擷取及 2 ms 輪詢。
983
+ 單獨 `--gpu` 啟用此組合,但不指定 DRM 裝置。Land 本身
984
+ 仍使用軟體合成,只有客戶端繪圖能使用 GPU。
985
+ 驅動支援仍有限:測試過的 Intel 路徑可運作,但測試的 Nouveau
986
+ 路徑產生空白或損壞圖片,因此不保證 NVIDIA 可用。
987
+
988
+ socket 目錄預設為 `$TMPDIR`,未設定 `TMPDIR`
989
+ 時則使用系統暫存目錄;明確設定的 `XDG_RUNTIME_DIR`
990
+ 優先。啟動合成器不需要設定環境。
991
+
992
+ 在另一個終端,將 Wayland 客戶端的 `XDG_RUNTIME_DIR` 設為該 socket
993
+ 目錄,`WAYLAND_DISPLAY` 設為合成器 socket 名稱(通常為 `wayland-buninu`,
994
+ 額外執行個體依序使用 `wayland-buninu1`、`wayland-buninu2`
995
+ 等),再啟動 Wayland 客戶端。當主機 `TMPDIR` 指向該目錄時,
996
+ chroot 內的客戶端可透過 `chroot --shared-tmp` 共用 socket。
997
+
998
+ `/bin/buninu-land` 啟動器將 `CASTY_BROWSER`
999
+ 設為 `/usr/lib/node_modules/buninu-land/compositor.js`,
1000
+ 並執行內附 Casty。`--casty` 將參數轉送 Casty;`--headless`、
1001
+ `--help`、`--version`、README 選項及預留的原生前端
1002
+ 則經過套件入口。套件的 CanvasKit WASM 若與系統副本位元組
1003
+ 相同,就共用系統副本;仍保留其載入器與授權檔案。
1004
+
1005
+ ### 封存工具及其他範例
1006
+
1007
+ 小型 `tar` 讀取封存檔自身的標頭來處理連結與清單,因此解壓時可
1008
+ 還原目錄、硬連結及所有符號連結,包括 `Bun.Archive`
1009
+ 拒絕的絕對目標,這也是解開後的 Alpine 根檔案系統能使用的
1010
+ 原因。`-t` 列出所有項目,不只一般檔案。建立封存檔仍遵循
1011
+ `Bun.Archive` 的限制:儲存一般檔案,但不儲存
1012
+ Unix 中繼資料、連結或空目錄。它支援 gzip 與 Bun
1013
+ 內建的 zstd,不支援 xz 或 bzip2。
1014
+
1015
+ - 有提供時,`--help` 會顯示命令說明或呈現其 Markdown 手冊。
1016
+ - 下方 `bun x` 範例需要網路:
1017
+ * `bun x` 從 npm registry 下載指定程式並執行,不會永久安裝。
1018
+ * 若首次失敗,試試 `bun pm cache rm`
1019
+ - 常見範例:
1020
+
1021
+ ```sh
1022
+ mount /dev/sda1 /mnt --mkdir
1023
+ mount -fv /dev/sda1 /mnt
1024
+ mount -t tmpfs -o size=64M tmpfs /tmp/x
1025
+ mount -t ntfs3 -o force /dev/sda3 /mnt/windows
1026
+ umount /mnt
1027
+ umount -R /mnt
1028
+
1029
+
1030
+ # 透過 bunproot 複製 Git 儲存庫
1031
+ bun x bunproot --git clone https://github.com/jjtseng93/bunproot
1032
+
1033
+ # 在 jmi 閱讀移除 ANSI 格式後的 bunproot Git 手冊
1034
+ bunterm 2
1035
+ bun x bunproot --git --readme | stripansi | jmi
1036
+
1037
+
1038
+
1039
+ ip link set eth0 up
1040
+ ip addr add 192.168.1.50/24 dev eth0
1041
+ ip route add default via 192.168.1.1
1042
+
1043
+ ip -br addr && ip route
1044
+ ip addr replace 192.168.1.50/24 dev eth0
1045
+ ip route replace default via 192.168.1.1
1046
+
1047
+ ps -eo pid,args
1048
+ ps -ef
1049
+ ps aux
1050
+ pspac
1051
+ top
1052
+ top -b -n 1
1053
+
1054
+ poweroff
1055
+ reboot
1056
+
1057
+ tar cvf /tmp/buninu.tar README.md package.json
1058
+ tar tvf /tmp/buninu.tar
1059
+ mkdir -p /tmp/buninu-copy
1060
+ tar xvf /tmp/buninu.tar -C /tmp/buninu-copy
1061
+
1062
+ # 加入 z 可建立 gzip 壓縮封存檔
1063
+ tar czvf /tmp/buninu.tar.gz README.md package.json
1064
+
1065
+ # 在另一個虛擬主控台:支援中日韓文字、emoji 與圖片的圖形終端機
1066
+ bunterm 2
1067
+ bunterm /dev/tty3 --font-size 13 -e bun /buninu/apps/jsmdcui/src/index.js --demo
1068
+ ```
1069
+
1070
+ `bunterm` 背後的圖形堆疊——framebuffer 模組、CanvasKit、
1071
+ 字型及終端——記載於 [graphics.md](graphics.md)。
1072
+
1073
+ ## 可選的根目錄切換與原生程式
1074
+
1075
+ 這些可選範例會下載並執行原生 Linux 程式,包含 Debian/
1076
+ Alpine 工具與 Chromium。它們不屬於 Buninu
1077
+ Linux 的 JS/WASM 使用者空間工具路線,也不在預設內
1078
+ 附應用程式中。若只想使用 JS/WASM 工具,可略過本節。內建
1079
+ `chroot` 命令本身是 Bun 腳本,但在所選根檔案系統內執行的
1080
+ 程式不一定要是 JavaScript 或 WebAssembly。
1081
+
1082
+ chroot 共用主機核心,不是安全沙箱。請使用可信任的根
1083
+ 檔案系統與軟體,下載需要網路。下方 Debian 與
1084
+ Alpine 範例針對 x86-64;chroot 不會模擬
1085
+ 其他 CPU 架構。
1086
+
1087
+ ### 在隔離根目錄使用瀏覽器前端
1088
+
1089
+ ```sh
1090
+ # 下載並進入 x64 Debian 根檔案系統
1091
+ # 確認已執行過以下命令:
1092
+ # bunterm 2 --font-size 13
1093
+ bun x bunproot --git --yes clone https://github.com/jjtseng93/js-udocker
1094
+ cd js-udocker
1095
+ bun udocker.js pull --platform=linux/amd64 debian:13
1096
+ bun udocker.js create --name db debian:13
1097
+ cd ~/.udocker/containers/db/ROOT
1098
+ chroot . /bin/bash
1099
+ apt update
1100
+ apt install --no-install-recommends ca-certificates curl unzip chromium-headless-shell fonts-noto-cjk fonts-noto-color-emoji git
1101
+ curl -fsSL https://bun.sh/install | bash
1102
+ bun x bunmsh
1103
+ # 原版 casty 是
1104
+ # @sanohiro/casty
1105
+ # 以下是我的分支版本
1106
+ # 修正部分問題並加入功能
1107
+ cd
1108
+ git clone https://github.com/jjtseng93/casty
1109
+ cd casty/bin
1110
+
1111
+ bun casty.js buninu.org
1112
+ # 若要 casty(YouTube)播放音效,先啟動 jspulse:
1113
+ # 請見「使用作業系統」下的「實驗性有聲影片播放」
1114
+ ```
1115
+
1116
+ 音效設定請見
1117
+ [播放有聲音的影片](#實驗性有聲影片播放)。
1118
+
1119
+ ### 最小根檔案系統
1120
+
1121
+ ```sh
1122
+ # 下載並進入 x64 Alpine 最小根檔案系統
1123
+ bun x bunproot --download-alpine-x64
1124
+ mkdir alpine
1125
+ cd alpine
1126
+ tar xvf ../alpine-minirootfs-*-x86_64.tar.gz
1127
+ cp $(which bun) bin
1128
+ chroot .
1129
+ apk add libgcc libstdc++
1130
+ ```
1131
+
1132
+ ### 使用既有根檔案系統
1133
+
1134
+ ```sh
1135
+ # 進入磁碟上的根檔案系統。/proc、/sys、/dev、/dev/pts、/run、/tmp
1136
+ # 及 /etc/resolv.conf 會自動掛載,退出時再移除掛載
1137
+ chroot /mnt
1138
+ chroot /mnt /bin/bun --version
1139
+ chroot -n /mnt /bin/sh # 略過自動掛載(明確指定的 -b 仍有效)
1140
+ ```
1141
+
1142
+
1143
+ 可重複使用 `-b` 選項來共用主機檔案與目錄,放在
1144
+ 根檔案系統路徑前:
1145
+
1146
+ ```sh
1147
+ # 將主機目錄掛載到客體內的不同路徑
1148
+ chroot -b /home/user/project:/work /mnt /bin/sh
1149
+
1150
+ # 省略客體路徑時,在客體內使用相同絕對路徑
1151
+ chroot -b /home/user/project /mnt /bin/sh
1152
+
1153
+ # 共用多個路徑,包含個別檔案
1154
+ chroot -b /home/user/project:/work -b /etc/hosts:/etc/hosts /mnt /bin/sh
1155
+
1156
+ # 共用主機暫存目錄,包含 Wayland socket
1157
+ export TMPDIR=/tmp
1158
+ chroot --shared-tmp /mnt /bin/sh
1159
+ # 等同於:
1160
+ chroot -b "$TMPDIR:/tmp" /mnt /bin/sh
1161
+ ```
1162
+
1163
+ `--shared-tmp` 展開成 `-b "$TMPDIR:/tmp"`
1164
+ 並取代自動建立的 `/tmp` tmpfs。必須設定 `TMPDIR`,且來源
1165
+ 路徑存在。此選項不改寫客體內的環境變數;若主機使用不同路徑,請在客體設定
1166
+ `TMPDIR=/tmp`。對 Buninu Land 客戶端,請將客體
1167
+ `XDG_RUNTIME_DIR=/tmp`、`WAYLAND_DISPLAY` 設為合成
1168
+ 器 socket 名稱,並確認主機 `TMPDIR` 是該 socket 所在目錄。
1169
+
1170
+ 主機路徑可為相對路徑,客體路徑必須是絕對路徑。缺少的
1171
+ 客體掛載目標會自動建立。目錄採遞迴綁定,重複目標以最後
1172
+ 一個參數為準。即使使用 `-k`,綁定失敗也會中止設定
1173
+ 並清理已掛載項目。通常命令結束時會移除掛載;`-k`/
1174
+ `--keep-mounts` 則在設定成功後保留。`-v` 回報
1175
+ 掛載與卸載過程。完整細節見 `chroot --help` 或
1176
+ [chroot 手冊](initramfs/usr/share/doc/buninu-linux/chroot.md)。
1177
+
1178
+ ## 環境與依賴
1179
+
1180
+ 預設 JS 建置使用主機 Bun。下方原生建置工具依賴適用於
1181
+ [舊版 shell 建置](#舊版建置工具)、可選的 Docker shell
1182
+ 工具鏈,以及獨立的原生 hello-world 範例。
1183
+
1184
+ ### 建置環境
1185
+
1186
+ 基準是原版 Debian 13(trixie)OCI 映像,本 PRoot
1187
+ 也是此環境;凡映像未內含的項目都算依賴。`debian:13`
1188
+ 與 `debian:13-slim` 含相同的 78 個套件,各
1189
+ `PATH` 目錄內的執行檔完全相同;slim 只移除文件、man 手冊
1190
+ 與語系。因此 105 MB 的 `debian:13-slim` 比 149
1191
+ MB 的完整版更適合作為起點,下方清單兩者皆適用。
1192
+
1193
+ 基礎映像已提供 `bash`、GNU `tar`、`gzip`、`sha256sum`、
1194
+ `mknod`、`find`、`sort`、`mkdir`、`mktemp`、`cp`、`rm`、
1195
+ `chmod`、`truncate`、`dd`、`printf`、`awk` 及 `dirname`,這些
1196
+ 腳本都直接使用它們。其餘工具必須另外加入。
1197
+
1198
+ ### 作業系統建置所需工具 ([第二節](#第二節作業系統與初始行程))
1199
+
1200
+ Buninu Linux 不需要編譯器:Bun 下載預先編譯的執行檔,UKI
1201
+ 以 `objcopy` 組裝。
1202
+
1203
+ ```sh
1204
+ apt install binutils-mingw-w64-x86-64 cpio curl dosfstools fakeroot mtools parted unzip
1205
+ ```
1206
+
1207
+ * **`binutils-mingw-w64-x86-64`** — `x86_64-w64-mingw32-objcopy`
1208
+ 將 `.osrel`、`.cmdline`、`.linux` 及 `.initrd` 區段附加至 EFI stub,
1209
+ `x86_64-w64-mingw32-objdump` 則讀取其中的 `ImageBase`。兩者都需要理解
1210
+ PE 的 binutils:ELF `objcopy` 無法寫入這些區段,`llvm-objcopy`
1211
+ 則拒絕 `--change-section-vma`。
1212
+ * **`cpio`** — 寫出 `build/initramfs.cpio.gz`。腳本傳入
1213
+ `--owner=0:0 --reproducible`,因此必須使用 GNU cpio,不能用 busybox
1214
+ applet。
1215
+ * **`curl`** — 下載 Alpine `.apk` 套件與 Bun 發行版 zip。
1216
+ * **`dosfstools`** — `mkfs.fat` 格式化
1217
+ ESP,其 `-h` 隱藏磁區數必須與分割區起始磁區一致。
1218
+ * **`fakeroot`** — 讓 `mknod` 與 `cpio` 不必有真正 root 權限就能在
1219
+ 封存檔記錄 root 擁有的字元裝置;PRoot 無法提供真正 root 權限。
1220
+ * **`mtools`** — `mmd`、`mcopy` 在 FAT 映像內建立
1221
+ `/EFI/BOOT` 並複製 UKI,不需掛載或 loop 裝置。
1222
+ * **`parted`** — 寫入保護用 MBR、主要及備份 GPT,以及含
1223
+ 類型 GUID 的 ESP 分割區項目。
1224
+ * **`unzip`** — 從發行版 zip 解出 `bun` 執行檔。
1225
+ * **`bun`**(或 **`node`**)— 在建置環境執行 `index.js`。
1226
+ + 在 bun 下,`--readme` 會呈現 Markdown;在 node 下則原樣印出。
1227
+
1228
+ ### 問候範例所需工具 ([第一節](#第一節問候範例))
1229
+
1230
+ hello-world EFI 應用程式需要 C/PE 工具鏈,以及共用的磁碟
1231
+ 映像工具:
1232
+
1233
+ ```sh
1234
+ apt install clang lld dosfstools mtools parted
1235
+ ```
1236
+
1237
+ * **`clang`** — 用 `--target=x86_64-pc-win32-coff`
1238
+ 將 `hello/hello.c` 編譯成 PE32+ 物件檔。在 trixie 對應 `clang-19`。
1239
+ * **`lld`** — 提供 `lld-link`,透過 `/subsystem:efi_application`
1240
+ 將 `hello/hello.obj` 連結為 EFI 應用程式。在 trixie 對應
1241
+ `lld-19`。
1242
+ * **`dosfstools`**、**`mtools`** 及 **`parted`** — 透過共用的
1243
+ `build-image.sh` 建立 FAT ESP,並包入 GPT `vda.img`。
1244
+
1245
+ ### 已退役的原生啟動程式
1246
+
1247
+ 已退役的 `test/build-init-bootstrap.sh` 也需要 `clang lld`。
1248
+ 它編譯歷史上的獨立 x86-64 `/init`;目前 Buninu Linux
1249
+ 路徑不使用也不編譯它。
1250
+
1251
+ ## 舊版建置工具
1252
+
1253
+ 以下是先前的原生工具鏈建置說明,保留作為預設 JS 工具之外的
1254
+ 選擇。請明確設定 `BUNINU_JS_TOOLS=0`
1255
+ 才會使用。文件環境為 Termux PRoot 中的 Debian
1256
+ 13,或一般 Debian/Ubuntu 安裝;Alpine 路徑仍
1257
+ 屬實驗性。所選階段開始前會回報缺少的 shell 建置工具。
1258
+
1259
+ - 若從原始碼建置,請複製到 Termux 家目錄,讓原生 Termux
1260
+ 與 PRoot 共用;兩者的 `~` 不同,但絕對路徑相同。
1261
+ - 開始前,先在 Debian/Alpine 安裝 Bun:
1262
+
1263
+ ```sh
1264
+ # Debian/Ubuntu
1265
+ apt update
1266
+ apt install curl unzip
1267
+
1268
+ # Alpine
1269
+ apk update
1270
+ apk add curl unzip bash libgcc libstdc++
1271
+
1272
+ curl -fsSL https://bun.sh/install | bash
1273
+ ```
1274
+
1275
+ ### 舊版直接透過套件建置
1276
+
1277
+ 安裝建置工具,進入要保存完成映像檔的
1278
+ 目錄,再執行已發布的套件:
1279
+
1280
+ ```sh
1281
+ # Debian/Ubuntu
1282
+ apt install binutils-mingw-w64-x86-64 cpio curl dosfstools fakeroot mtools parted unzip
1283
+
1284
+ # Alpine
1285
+ apk add bash coreutils tar curl unzip parted dosfstools mtools libgcc libstdc++
1286
+
1287
+ mkdir -p /data/data/com.termux/files/home/buninu-build
1288
+ cd /data/data/com.termux/files/home/buninu-build
1289
+
1290
+ export PATH=$HOME/.bun/bin:$PATH
1291
+ export BUNINU_JS_TOOLS=0
1292
+
1293
+ bun x buninu-linux --version
1294
+
1295
+ # Debian/Ubuntu
1296
+ bun x buninu-linux -fb --real --export
1297
+
1298
+ # Alpine:在 shell 流程內用 JS 處理 cpio 與 UKI 組裝
1299
+ export BUNINU_JS_CPIO=1
1300
+ export BUNINU_JS_UKI=1
1301
+ bun x buninu-linux -fb --real --export
1302
+ ```
1303
+
1304
+ `--export` 將完成的 `vda.img` 從 bunx 套件目錄複製到執行命令時所在
1305
+ 目錄,命名為 `buninu-linux-<version>.img`。
1306
+
1307
+ ### 舊版從原始碼建置
1308
+
1309
+ 在原生 Termux 中:
1310
+
1311
+ ```sh
1312
+ git clone https://github.com/jjtseng93/buninu-linux.git ~/buninu-linux
1313
+ ```
1314
+
1315
+ 在 PRoot 的 Debian 13 中:
1316
+
1317
+ ```sh
1318
+ apt install binutils-mingw-w64-x86-64 cpio curl dosfstools fakeroot mtools parted unzip
1319
+ cd /data/data/com.termux/files/home/buninu-linux
1320
+ BUNINU_JS_TOOLS=0 bun ./index.js -fb --real --export
1321
+ ```
1322
+
1323
+ 這會下載鎖定的輸入、選取真機模組、建置 `vda.img` 並匯出
1324
+ `buninu-linux-<version>.img`。
1325
+ 接著請見[寫入映像檔到隨身碟](#寫入映像檔到隨身碟)。
1326
+
1327
+ ## 實作細節
1328
+
1329
+ ### 第一節問候範例
1330
+
1331
+ - `hello/hello.c` 是獨立的 PE32+ EFI 應用程式,安裝於可移除
1332
+ 媒體的備援路徑 `EFI/BOOT/BOOTX64.EFI`。
1333
+ - 它是基本開機測試,不是完整的 Buninu Linux
1334
+
1335
+ ```sh
1336
+ ./hello/build-hello.sh # 在 PRoot 中
1337
+ ./build-image.sh # 在 PRoot 中
1338
+ sudo dd if=vda.img of=/dev/sdX bs=4M conv=fsync status=progress
1339
+ ```
1340
+
1341
+ 確認 `/dev/sdX` 是整個目標 USB 裝置後,在
1342
+ 實體 x86-64 UEFI 機器開機。它向韌體主控台寫出
1343
+ `Hello world from x64 UEFI!` 並等待;按任意鍵回到韌體介面。
1344
+
1345
+ `build-image.sh` 與[第二節](#第二節作業系統與初始行程)共用,請見[磁碟配置](#磁碟配置)。
1346
+
1347
+ ### 第二節作業系統與初始行程
1348
+
1349
+ 以官方 Alpine 套件組裝的未簽章 x64 統一核心映像,將 Bun
1350
+ 作為 init 行程,取代 hello-world 應用程式:
1351
+
1352
+ ```sh
1353
+ # 真機映像,在 PRoot Debian 中
1354
+ bun ./index.js -fb --real --export
1355
+
1356
+ # bun x buninu-linux -fb --real --export
1357
+ ```
1358
+
1359
+ `index.js` 是統一入口(`npm run fetch` 與 `npm run pack`
1360
+ 也呼叫它)。真機映像階段依下載 → 建置的順序執行:
1361
+
1362
+ #### 建置旗標
1363
+
1364
+ 下載與建置預設採用 JS 工具。解開 npm 套件需要主機 Bun。只有
1365
+ `BUNINU_JS_TOOLS=0`、`off` 或 `false` 會
1366
+ 停用此路徑(不分大小寫,忽略前後空白);未設定或空值則保持啟用。即使有
1367
+ `--docker`,JS 工具仍略過 Docker。若要使用容器工具鏈,執行
1368
+ `BUNINU_JS_TOOLS=0 bun index.js -fb --docker`。執行階段仍使用
1369
+ `run-qemu.sh` 與主機 QEMU。
1370
+
1371
+ | 旗標 | 執行內容 | 使用時機 |
1372
+ | --- | --- | --- |
1373
+ | `-f`、`--fetch` | 預設 `scripts/fetch.js`;shell 路徑:`fetch-alpine.sh`、`fetch-bun.sh`、`fetch-npm.sh` | 首次複製原始碼,或更新鎖定版本後 |
1374
+ | `-b`、`--build` | 預設 `scripts/build.js`;shell 路徑:`build-uki.sh`、`build-image.sh` | 修改 `initramfs/init.js` 或核心命令列後 |
1375
+ | `--arch ARCH` | 明確選取 `x86_64`(下載/建置預設)或 `aarch64`;單獨 `-r` 偵測上次建置的 UKI | 建置或執行特定客體架構 |
1376
+ | `--docker` | 停用 JS 工具時,在 `Dockerfile` 容器內執行 `-f`/`-b`(macOS shell 模式自動使用) | 不在主機安裝 shell 工具鏈而使用它 |
1377
+
1378
+ `--export` 是建置後選項:`-b` 完成後,將
1379
+ `vda.img` 複製到執行命令時所在目錄,命名為
1380
+ `buninu-linux-<version>.img`(`--arch aarch64`
1381
+ 則為 `buninu-linux-<version>-aarch64.img`)。因此
1382
+ 需要 `-b`/`--build`,也是保存 npx/bunx 所建映像的建議方法:
1383
+
1384
+ ```sh
1385
+ bun x buninu-linux -fb --real --export
1386
+ ```
1387
+
1388
+ `--linux-lts` 選取 Alpine 通用 LTS 核心。
1389
+ `--real` 隱含 `--linux-lts` 並為真機建置:將 `tty0`
1390
+ 設為主要主控台,包含一般筆電與桌機所需的 xHCI/USB HID、常見有線
1391
+ 網卡、Android USB 網路共享、儲存及 ACPI 電源模組。
1392
+
1393
+ 真機的完整映像流程是 `-fb --real`,修改後
1394
+ 重建則用 `-b --real`。開始前,`index.js`
1395
+ 檢查所有必需工具是否在 `PATH` 中,列出缺少項目,
1396
+ 避免執行到一半才失敗。shell 腳本負責實際工作,各自仍能
1397
+ 獨立執行。
1398
+
1399
+ ```text
1400
+ index.js entry point: -f / -b / -r / --arch / --docker / --export / --linux-lts / --real
1401
+ Dockerfile Debian-based oven/bun:1.4.2 plus the shell build toolchain
1402
+ fetch-alpine.sh [fetch] kernel, EFI stub, musl, network/input/display modules
1403
+ fetch-bun.sh [fetch] Bun, libstdc++, libgcc
1404
+ fetch-npm.sh [fetch] pinned browser, land, casty, jspulse and jspinyin tarballs (download only)
1405
+ build-uki.sh [build] UKI; calls scripts/pack-initramfs.sh
1406
+ build-image.sh [build] GPT disk image; shared with the hello-world EFI
1407
+ run-qemu.sh [run] QEMU q35 (x86_64) or virt (aarch64), KVM/HVF/TCG
1408
+ scripts/arch.sh per-architecture pins, hashes and names, sourced by all of the above
1409
+ scripts/fetch.sh hash-checked download helper, sourced by fetch-*.sh
1410
+ scripts/pack-initramfs.sh cpio archive with the device nodes
1411
+ hello/ hello-world EFI: hello.c and build-hello.sh (x86_64 only)
1412
+ test/ the retired C bootstrap and its build script (x86_64 only)
1413
+ test/host/ build-and-boot test on a fresh Linux amd64/arm64 host, in Docker
1414
+ initramfs/ init.js, commands, userspace: the same for every architecture
1415
+ native/<arch>/ musl and the GCC runtime (committed); bun and modules (fetched)
1416
+ ```
1417
+
1418
+ `--real` 的輸入為 Alpine v3.24 `linux-lts-6.18.59-r0`、musl
1419
+ `1.2.6-r2`、`systemd-efistub-260.2-r0`、`libstdc++`/`libgcc`
1420
+ `15.2.0-r5`,以及 Bun 1.4.2 `linux-x64-musl-baseline`。aarch64
1421
+ 客體使用 Alpine aarch64 儲存庫的相同版本與 Bun 的 `linux-aarch64-musl`。
1422
+ 不包含 BusyBox 或傳統原生使用者空間;命令由 Bun 與 JavaScript 的
1423
+ Buninu 使用者空間提供。
1424
+
1425
+ 每個步驟皆可重複執行而保持相同結果,`-f` 不會重下載有效
1426
+ 快取:`scripts/fetch.sh` 以各鎖定
1427
+ SHA-256 作為快取鍵,`downloads/<arch>/` 中雜湊正確的
1428
+ 檔案直接沿用,缺少、截斷、過時或遭竄改的檔案則重新下載,且必須
1429
+ 通過同一雜湊驗證,腳本才會解開。更新版本同時更換檔名與雜湊,因此
1430
+ 一定會重新取得。
1431
+
1432
+ 五個應用套件與精確版本鎖定於
1433
+ [`scripts/npm-packages.md`](scripts/npm-packages.md),以該清單為映像依據。
1434
+ 下載時絕不即時解析 `latest` 或版本範圍。
1435
+ 各 registry tarball 都先依發布的 SHA-512 integrity 驗證,
1436
+ 再將 SHA-256 記入該共用鎖定清單。
1437
+
1438
+ 清單使用固定且相容 YAML 的區塊:以雙引號包住
1439
+ `"package@version":` 標頭,後接兩行 ` - `,分別包含
1440
+ registry URL 與 `sha256:HEX`。允許空行及 `#` 註解。
1441
+ `.md` 副檔名讓 `bun scripts/npm-packages.md`
1442
+ 可顯示清單。Bun 用 `Bun.YAML.parse`
1443
+ 解析;Node 與 shell 也支援相同嚴格格式,不需安裝
1444
+ YAML 解析器。快取檔名由套件名及版本推得,保留既有快取名稱。
1445
+
1446
+ 兩種下載路徑都直接從 `registry.npmjs.org` 下載至
1447
+ x86_64 與 aarch64 共用的 `downloads/npm/`,
1448
+ 無論命中快取或重新下載,都驗證鎖定 SHA-256。下載期間不
1449
+ 執行 npm/Bun 套件安裝、生命週期腳本或依賴解析。
1450
+
1451
+ 打包時,`scripts/stage-npm.js`(JS 工具)或
1452
+ `scripts/stage-npm.sh`(shell 工具)再次檢查 SHA-256,去掉封
1453
+ 存檔最前面一層路徑後,解到暫存樹的 `/usr/lib/node_modules/<package>`。
1454
+ 有 scope 的名稱保留 `@scope/name` 目錄。不執行安裝腳本
1455
+ 或依賴解析。JS 解壓使用 initramfs 的 JS `tar`,需要
1456
+ 主機 Bun;shell/Docker 解壓使用主機 `tar`,不需 Bun。
1457
+ 打包不修改原始 `initramfs/` 與專案 `package.json`。
1458
+
1459
+ 映像內的 `/usr/lib/package.json` 包含五個精確依賴版本及
1460
+ 標準 `node_modules/.bin` 連結。這保留一般套件管理器配置,供
1461
+ 之後 `cd /usr/lib`、`bun i --backend=copyfile`
1462
+ 使用;不會憑空製作 lockfile。單獨 `bun i` 保留
1463
+ 鎖定版本,不更新為較新版本。此處尚未實作跨開機持久保存或套件更新命令。
1464
+
1465
+ 解壓時只有 `buninu-browser` 排除
1466
+ `package/usr/lib/canvaskit` 與 `package/usr/share/fonts`;
1467
+ `usr/README.md`
1468
+ 及其他內容皆保留。發行版的 `/bin/buninu-browser`
1469
+ 啟動器在啟動時建立缺少的資源目錄與相對連結:套件
1470
+ 的 `usr/lib/canvaskit` 指向
1471
+ `/lib/canvaskit`,`usr/share/fonts`
1472
+ 指向 `/usr/share/fonts`。既有資源不動,包含後續
1473
+ npm 安裝還原的資源。啟動器直接執行打包的 casty,不透過
1474
+ `bunx`/`npx` 下載;其他前端與選項交由套件啟動器。請使用
1475
+ 發行版命令完成資源設定,直接呼叫 npm 入口會略過此掛鉤。除此之外,解
1476
+ 出的套件保持原樣,包含授權與原始碼檔案。這個步驟不啟動服務,也不把
1477
+ jspinyin 整合進終端。
1478
+
1479
+ `/bin/jspulse` 直接從 `/usr/lib/node_modules`
1480
+ 匯入已安裝套件的入口。`/bin/jspinyin` 則以 `--tui` 啟動
1481
+ `/buninu/apps/jsmdcui/src/index.js` 的系統 jsmdcui,傳入使用者參數後再接
1482
+ `/usr/lib/node_modules/@drxiaozhi/jspinyin/im.md`。
1483
+ 它略過上游 `bun x jsmdcui` 啟動器,所以啟動此命令不會下載 jsmdcui。兩者
1484
+ 皆是小型可執行 JavaScript 檔案,沒有 shell 包裝。在終端執行
1485
+ `jspulse --alsa` 或 `jspinyin` 即可。
1486
+
1487
+ 若只要下載這些應用程式封存檔:
1488
+
1489
+ ```sh
1490
+ bun scripts/fetch-npm.js # 內建 fetch;也可用 Node.js 執行
1491
+ ./fetch-npm.sh # curl + sha256sum,也適用 Docker 內部
1492
+ ```
1493
+
1494
+ #### 建置流程
1495
+
1496
+ 主要的 `bun ./index.js -fb --real` 流程依序執行
1497
+ 下列步驟,各步驟寫出下一步要讀取的檔案。若選用 `--export`,最後
1498
+ 會將完成的 `vda.img` 複製到執行命令時所在目錄。
1499
+
1500
+ ##### 流程輸入與輸出
1501
+
1502
+ | 腳本 | 讀取 | 寫出 |
1503
+ | --- | --- | --- |
1504
+ | `fetch-alpine.sh` | Alpine CDN | `kernel/<arch>/vmlinuz-<flavor>`、`kernel/<arch>/linuxx64.efi.stub`(`linuxaa64.efi.stub`)、`native/<arch>/lib/ld-musl-<arch>.so.1`,以及 `native/<arch>/lib/modules/` 下選取的網路、儲存、輸入、電源與檔案系統模組,附精簡模組索引 |
1505
+ | `fetch-bun.sh` | GitHub、Alpine CDN | `native/<arch>/bin/bun`、`native/<arch>/lib/{libc.musl-<arch>.so.1,libstdc++.so.6,libgcc_s.so.1}` |
1506
+ | `fetch-npm.sh`/`scripts/fetch-npm.js` | npm registry,`scripts/npm-packages.md` 的固定 URL 與 SHA-256 | `downloads/npm/*.tgz`;打包時再解到 `/usr/lib/node_modules` |
1507
+ | `scripts/pack-initramfs.sh` | `initramfs/`,再以 `native/<arch>/` 覆蓋 | `build/initramfs.cpio.gz` |
1508
+ | `build-uki.sh` | 該封存檔、核心及 stub | `build/cmdline`、`build/os-release`、`vda/EFI/BOOT/BOOTX64.EFI`(`BOOTAA64.EFI`) |
1509
+ | `build-image.sh` | `vda/EFI/BOOT/BOOTX64.EFI`(`BOOTAA64.EFI`) | `vda.img` |
1510
+
1511
+ `build-uki.sh` 會自行呼叫 `scripts/pack-initramfs.sh`,因此
1512
+ 很少直接執行後者。
1513
+
1514
+ 各階段是巢狀的:initramfs 嵌入 UKI,UKI 再嵌入磁碟映像。因此
1515
+ 即使只修改 `initramfs/init.js` 一行,仍需要以下兩個步驟:
1516
+
1517
+ ```sh
1518
+ bun ./index.js -b --real
1519
+ ```
1520
+
1521
+ 核心命令列也相同:`build-uki.sh` 將它寫入
1522
+ `build/cmdline` 並編入 UKI。開機時不會從磁碟
1523
+ 讀取該檔案。
1524
+
1525
+ #### 統一核心映像配置
1526
+
1527
+ `build-uki.sh` 透過 `objcopy` 在 systemd 對應架構
1528
+ 的 EFI stub 附加區段,使用計算出的 VMA,因為 `objcopy` 不會自動
1529
+ 配置。以下大小與偏移描述目前 x86_64 `--real` 映像;aarch64
1530
+ 使用較大的 `linuxaa64.efi.stub`,因此 `.osrel`
1531
+ 與 `.cmdline` 會位移,每次建置都測量輸入以避免重疊:
1532
+
1533
+ ##### 統一核心映像區段
1534
+
1535
+ | 區段 | 相對映像基底的偏移 | 內容 | 大小 |
1536
+ | --- | --- | --- | --- |
1537
+ | `.text` | +0x0 | stub 本身 | 66 KB |
1538
+ | `.osrel` | +0x20000 | `build/os-release` | 78 B |
1539
+ | `.cmdline` | +0x30000 | `build/cmdline` | 136 B |
1540
+ | `.linux` | +0x2000000 | `kernel/x86_64/vmlinuz-lts` | 14.5 MB |
1541
+ | `.initrd` | +0x3000000 | `build/initramfs.cpio.gz` | 44.6 MB |
1542
+
1543
+ 目前 x86_64 `--real` 的結果是單一 59.3 MB
1544
+ PE32+ 檔案,包含核心、initramfs 與命令列。其他架構、核心
1545
+ 類型與原始碼版本可能產生不同大小。
1546
+
1547
+ #### 磁碟配置
1548
+
1549
+ `build-image.sh` 不需要掛載、loop 裝置或
1550
+ root 權限。它格式化獨立 FAT32 映像,以 mtools 填入
1551
+ 檔案、`parted` 建立 GPT,再用 `dd`
1552
+ 的 `conv=notrunc,sparse` 將檔案系統寫入分割區。
1553
+ `mkfs.fat -h 2048` 很重要:FAT 隱藏磁區數必須符合分割區起始磁區,否則某些
1554
+ 韌體會拒絕該磁碟區。
1555
+
1556
+ ```text
1557
+ LBA 0 protective MBR
1558
+ LBA 1..33 primary GPT
1559
+ LBA 2048..262110 ESP, FAT32 "EFIBOOT", type GUID C12A7328-F81F-11D2-BA4B-00A0C93EC93B
1560
+ /EFI/BOOT/BOOTX64.EFI x86_64 UKI
1561
+ /EFI/BOOT/BOOTAA64.EFI aarch64 UKI (in an aarch64 image)
1562
+ LBA 262111.. backup GPT
1563
+ ```
1564
+
1565
+ 映像至少為 128 MiB 的稀疏檔案,依 EFI 內容自動增長
1566
+ (每次 64 MiB,預留 FAT 中繼資料及可用空間),採 1
1567
+ MiB 對齊,尾端保留 34 個磁區
1568
+ 給備份 GPT。`EFI/BOOT/BOOTX64.EFI` 與
1569
+ `EFI/BOOT/BOOTAA64.EFI` 是各架構的可移除媒體備援路徑,
1570
+ 因此對應韌體會直接執行映像內的檔案,不需任何 NVRAM 開機項目。
1571
+
1572
+ #### 真機開機細節
1573
+
1574
+ 真機開機鏈為韌體 → UKI stub → 其內嵌的 `.linux`
1575
+ /`.initrd`/`.cmdline` 區段 → 核心 →
1576
+ `rdinit=/bin/bun`。`--real` 使用 Alpine `linux-lts`,
1577
+ 包含 xHCI 與 USB HID 模組鏈,目前鎖定核心使用以下完整命令列:
1578
+
1579
+ ```text
1580
+ console=ttyS0,115200 console=tty0 REAL_MACHINE=1 panic=0 PATH=/bin KERNEL_RELEASE=6.18.59-0-lts rdinit=/bin/bun -- -e import('/init.js')
1581
+ ```
1582
+
1583
+ 保留序列核心日誌,最後指定的主控台則讓
1584
+ `/dev/console` 與 Bun REPL 使用
1585
+ 實體螢幕及鍵盤。此路徑已在真機測試成功。
1586
+
1587
+ #### 虛擬機開發
1588
+
1589
+ 此可選路徑已在原生 Android Termux,以及搭配 QEMU 8.2.2、
1590
+ TCG 與 OVMF 的 Ubuntu 24.04 雲端虛擬機測試。在原生
1591
+ Termux,請另外安裝執行工具,與 PRoot 建置依賴分開:
1592
+
1593
+ ```sh
1594
+ pkg install qemu-system-x86-64
1595
+ ```
1596
+
1597
+ 該套件在 QEMU 執行檔附近的 `$PREFIX/share/qemu/edk2-x86_64-code.fd`
1598
+ 提供 OVMF,這是 `run-qemu.sh` 在 `OVMF_FILE` 與 Debian 的
1599
+ `/usr/share/OVMF/OVMF_CODE_4M.fd` 之後搜尋的位置(Homebrew
1600
+ 的 `share/qemu` 也用同樣方式尋找)。建置時不加 `--real`,就會選取 Alpine `linux-virt`、省略真
1601
+ 機模組集,並將 `ttyS0` 放最後,讓序列標準輸入輸出擁有 `/dev/console`:
1602
+
1603
+ ```text
1604
+ console=tty0 console=ttyS0,115200 panic=0 PATH=/bin KERNEL_RELEASE=6.18.59-0-virt rdinit=/bin/bun -- -e import('/init.js')
1605
+ ```
1606
+
1607
+ 使用以下命令建置並開機:
1608
+
1609
+ ```sh
1610
+ bun ./index.js -fb
1611
+
1612
+ # 在 PRoot 內使用 Termux 原生 qemu-system-x86_64 時,
1613
+ # 將它加入 PATH;其 OVMF 位於附近:
1614
+ PATH="/data/data/com.termux/files/usr/bin:$PATH" \
1615
+ bun ./index.js -r
1616
+ ```
1617
+
1618
+ 若 QEMU 安裝於目前 Debian 環境內,直接 `bun ./index.js -r`
1619
+ 即可;`run-qemu.sh` 會使用 Debian 的 OVMF 路徑。
1620
+
1621
+ `bun ./index.js -r` 執行 `run-qemu.sh`,在
1622
+ q35(aarch64 映像則為 `virt`)啟動 `vda.img`,
1623
+ 配備 1 GiB、virtio 磁碟、virtio-net 使用者網路、不開
1624
+ 顯示器,第一個序列埠接到標準輸入輸出。客體與主機 CPU 相符時使用 KVM 或
1625
+ Hypervisor.framework,其餘使用 TCG;請見[在桌面系統建置及測試虛擬機](#在桌面系統建置及測試虛擬機)。`--` 後的內容附加到 QEMU 命令列。Ctrl
1626
+ -C 結束 QEMU。離開 REPL 不會結束工作階段,`init.js` 會重啟
1627
+ 它,因為 PID 1 退出會造成核心 panic。
1628
+
1629
+ 僅供 QEMU 的 CLI 階段是 `-r`/`--run`;`-fbr` 是完整
1630
+ 虛擬機流程,`-br` 是修改後建置開機循環,`--` 後參數原樣轉送,例如
1631
+ `-r -- -m 1G`。對應儲存庫入口為 `run-qemu.sh`。
1632
+ 若要改測[第一節](#第一節問候範例)的 EFI hello-world 映像,先建置它,再執行
1633
+ 相同 `-r` 階段;OVMF 透過 COM1 提供主控台。舊的
1634
+ `fetch-plus-build.sh` 包裝等同虛擬機 `-fb`
1635
+ 階段,不選取 `--real`。`npm start` 呼叫執行階段。
1636
+
1637
+ 若要更短的 initramfs 測試循環,可略過 UKI 與磁碟映像:
1638
+
1639
+ ```sh
1640
+ qemu-system-x86_64 -machine q35,accel=tcg -cpu max -m 512M \
1641
+ -kernel kernel/x86_64/vmlinuz-virt -initrd build/initramfs.cpio.gz \
1642
+ -append "console=ttyS0,115200 panic=0 PATH=/bin rdinit=/bin/bun -- -e console.log(1+1)" \
1643
+ -nic user,model=virtio-net-pci -display none -serial stdio -no-reboot
1644
+ ```
1645
+
1646
+ 這類測試之間只需重新執行 `./scripts/pack-initramfs.sh`。
1647
+ 由於 `panic=0`,panic 會讓客體停住,此時按 Ctrl-C。
1648
+ 此捷徑不測試 UKI stub、GPT、實體主控台或硬體驅動;完成後仍須用
1649
+ `bun ./index.js -b --real` 在真正 UEFI 路徑驗證結果。
1650
+
1651
+ ##### 虛擬機網路
1652
+
1653
+ 網卡使用 QEMU 使用者模式網路(SLIRP):客體為 NAT 後的 `10.0.2.15/24`,
1654
+ 閘道是 `10.0.2.2`,DNS 是 `10.0.2.3`,因此可以向外連線——開機
1655
+ 時 `fetch example.com` 可驗證——但若未轉送連接埠,外部無法連入。
1656
+ `PORTS` 用來設定轉送,以空格分隔 `host[:guest]`,`guest`
1657
+ 預設與 `host` 相同:
1658
+
1659
+ ```sh
1660
+ PORTS="18080" bun ./index.js -r # 主機 127.0.0.1:18080 → 客體 :18080
1661
+ PORTS="18080 2222:22" bun ./index.js -r # ……另加主機 127.0.0.1:2222 → 客體 :22
1662
+ ```
1663
+
1664
+ `run-qemu.sh` 將每個項目轉為 `hostfwd=tcp:127.0.0.1:H-:G`。
1665
+ 依 SLIRP 的轉送方式,有兩點需要注意:
1666
+
1667
+ * 主機端只綁定 `127.0.0.1`,不會暴露到裝置自身的
1668
+ 網路介面。移除位址(`hostfwd=tcp::H-:G`)可
1669
+ 改變此行為。
1670
+ * 轉送連線抵達客體的 `eth0` 位址,因此內部服務必須監聽
1671
+ `0.0.0.0`(或 `10.0.2.15`)。綁定客體自身
1672
+ `127.0.0.1` 的服務收不到外部流量;已用兩個轉送連接埠
1673
+ 上的伺服器分別綁定兩種位址驗證。
1674
+
1675
+ 客體內的 `127.0.0.1` 仍可供內部程式使用:`init.js` 掛
1676
+ 載完成後立即啟用 `lo`,此時核心指派 `127.0.0.1/8`。
1677
+ 若缺少此步驟,所有綁定 `127.0.0.1` 的操作都會以
1678
+ `EADDRNOTAVAIL` 失敗。
1679
+
1680
+ 以下兩個行為屬於預期:
1681
+
1682
+ * **開機會修改 `vda.img`。** 韌體以唯讀方式掛載,且沒有獨立變數儲存
1683
+ 區,因此 OVMF 將非揮發性變數存為 ESP 上的 `/NvVars`。每次
1684
+ 開機後 `git status` 都會回報 `vda.img` 已修改。
1685
+ * **QEMU 會對 `vda.img` 加寫入鎖。** 第二個執行個體會以
1686
+ `Failed to get "write" lock` 失敗;若要同時執行兩個,請先複製映像。
1687
+
1688
+ #### 命令實作
1689
+
1690
+ 前述 `/bin` 命令是建構於 `/lib` 兩個共用模組之上的
1691
+ Bun 腳本。`--help` 使用 `Bun.markdown.ansi`
1692
+ 將 Markdown 手冊呈現為含超連結的內容,並在最後印出頁面
1693
+ 的絕對路徑,以便直接讀取或編輯。共用部分如下:
1694
+
1695
+ * `/lib/dlopen.js` — 以 `bun:ffi` 綁定 `/lib/libc.musl-<arch>.so.1`
1696
+ (`mount`、`umount2`、`ioctl`、`socket`、`sync`、`reboot`、`syscall` 等),
1697
+ 提供 `errno`/`strerror`、`SysError` 類別及各命令 `--help`
1698
+ 使用的 `showDocument()` 輔助函式。`process.arch` 決定
1699
+ libc 檔名與 `finit_module` 系統呼叫編號,後者是這些命令唯一直接使用的原始系統呼叫。`init.js` 保有自己的綁定副本,因為它在
1700
+ `/proc` 存在之前執行,無法匯入其他內容。
1701
+ * `/lib/modprobe.js` — `modprobe(name)` 解析
1702
+ `/lib/modules/<release>/` 下的 `modules.alias` 與
1703
+ `modules.dep`,依序為各依賴呼叫 `finit_module`。核心在此沒有可呼叫的
1704
+ `/sbin/modprobe`,因此 `mount` 自行預載 `ext4`+`jbd2`、`vfat`+NLS
1705
+ 表、`ntfs3`、`sd_mod`、`nvme` 等。
1706
+
1707
+ 映像包含哪些模組由 `fetch-alpine.sh` 清單決定,其中的
1708
+ `select_module` 輔助函式從 Alpine `modules.dep`
1709
+ 帶入依賴;`--real` 加入常見儲存路徑(`sd_mod`、`ahci`、
1710
+ `ata_generic`、`pata_acpi`、`nvme`、Intel
1711
+ `vmd`、`usb-storage`、`uas`)、有線網卡、Android USB 網路共享
1712
+ 驅動及 ACPI 電源驅動。Alpine 核心將這些都建成模組;自行建置核心並將它們
1713
+ 設為 `=y` 也能以相同方式運作,只是載入器找不到需要載入的項目。
1714
+
1715
+ #### 終端機影像傳輸
1716
+
1717
+ 原生 bunterm 依 framebuffer 的位元欄位宣告偏好的原始像素格式:支援的 32 位元排列採用 BGRA 或 RGBA,其餘回報 PNG。新版 Casty、buninu-browser 與 Land 透過 Kitty 共用檔案傳輸自動協商;BGRA 使用私有格式 `f=1111970369`,RGBA 使用標準 `f=32`。其他終端機與 jsgotty 維持既有協議。
1718
+
1719
+ 原始像素暫存影格在可用時採用 mmap。bunterm 會在 parser、renderer 與處理中的封包全部使用完畢後立即釋放映射,避免累積舊影格到之後的 GC 才整批回收而停頓。共用的 placement 仍會保留影像;不支援立即釋放時則退回垃圾回收。
1720
+
1721
+ #### 尚未掛載時進入腳本環境
1722
+
1723
+ 預設 `--real` 映像內嵌以下核心命令列(此處為目前
1724
+ 鎖定的 LTS 版本):
1725
+
1726
+ ```text
1727
+ console=ttyS0,115200 console=tty0 REAL_MACHINE=1 panic=0 PATH=/bin KERNEL_RELEASE=6.18.59-0-lts rdinit=/bin/bun -- -e import('/init.js')
1728
+ ```
1729
+
1730
+ 實體螢幕(`tty0`)是最後指定的主控台,因此擁有 PID 1 的
1731
+ 標準串流;`ttyS0` 仍可提供序列日誌。核心直接 exec
1732
+ `/bin/bun`,中間沒有原生啟動程式;`init.js` 的第
1733
+ 一個動作是透過 `bun:ffi` 掛載 `/proc`、`/sys`、
1734
+ `/dev`、`/tmp` 與 `/dev/pts`。`--` 前的
1735
+ 每個項目都需要 `=`,因為核心會把裸字附加到 init argv,而
1736
+ 非視為環境變數指派;`--` 後的所有內容原樣成為 `argv[1..]`,
1737
+ `argv[0]` 設為 `rdinit=` 路徑。除此之外參數順序不限,所以將
1738
+ `rdinit=` 放最後,讓行尾讀起來就是最後執行的 `bun -e …`。
1739
+
1740
+ 要讓這個流程運作,必須分別滿足兩個條件。
1741
+
1742
+ **入口必須是 `-e`,不能是檔案。** `bun /init.js` 先開啟入口檔案,再以
1743
+ `readlink("/proc/self/fd/N")` 正規化路徑(位於
1744
+ `src/runtime/cli/run_command.rs` 的 `maybe_open_with_bun_js`);
1745
+ 失敗便放棄,這正是沒有 /proc 的開機環境會遇到的情況。`-e` 不開啟入口檔案,因此略過
1746
+ 此步驟。Bun 啟動時*不會*解析 `/proc/self/exe`——該結果由
1747
+ `process.execPath`/`process.argv[0]` 延後快取,失敗時退回
1748
+ `argv[0]`——其餘啟動時讀取 `/proc` 的項目(`vm/overcommit_memory`、
1749
+ `vm/mmap_min_addr`、`self/cgroup`、`self/statm`)
1750
+ 失敗都不致命。
1751
+
1752
+ **Bun 啟動前必須存在 `/dev/urandom`。** JSC 的 `OSRandomSource`
1753
+ 無法開啟它時會呼叫 `CRASH()`,而作為 PID 1 時這會立即造成核心 panic:
1754
+
1755
+ ```text
1756
+ panic(main thread): abort() called
1757
+ traps: bun[1] trap invalid opcode
1758
+ Kernel panic - not syncing: Attempted to kill init!
1759
+ ```
1760
+
1761
+ 當時尚未掛載 devtmpfs,因此 `scripts/pack-initramfs.sh`
1762
+ 直接在 cpio 封存檔記錄 `urandom`,以及核心在 exec
1763
+ 前開啟為 init 的 fd 0/1/2 的 `console`,和其他
1764
+ 少數無害節點。
1765
+ 使用 `--real` 時,`tty0` 列在 `console=` 參數
1766
+ 最後,使實體螢幕擁有 `/dev/console`;`ttyS0` 仍可輸出
1767
+ 序列核心日誌。
1768
+
1769
+ initramfs 中沒有 `/init`;核心僅透過 `rdinit=` 進入 Bun。已
1770
+ 退役的原生啟動程式保留在 `test/build-init-bootstrap.sh`,
1771
+ 可重建為 `/init`,用於在 Bun 啟動前掛載內容,或以不同
1772
+ 參數 exec Bun 來逐步縮小開機失敗原因。建置、重新打包後,以
1773
+ `rdinit=/init` 開機。上述 `/dev/urandom`
1774
+ 需求,就是透過改變此啟動程式在 exec 前掛載哪些檔案系統
1775
+ 而找出的。
1776
+
1777
+ #### 初始化腳本的工作
1778
+
1779
+ 它安裝訊號處理器,透過 `bun:ffi` 載入 musl 的獨立實體
1780
+ 副本,掛載 `/proc`、`/sys`、`/dev`、`/tmp`
1781
+ 與 `/dev/pts`(若未掛載 devpts,每次開啟 pty
1782
+ 都會以 `ENODEV` 失敗,因為 `/dev/ptmx` 透過
1783
+ `/dev/pts/ptmx` 解析),開啟 Num Lock、印出問候訊息
1784
+ 並啟動 `node:repl`。核心以 Num Lock 關閉狀態啟動各虛擬
1785
+ 主控台,數字鍵盤因此會輸入方向鍵而非數字;init 透過 `KDSKBLED`
1786
+ 為每個已存在的主控台設定目前狀態與重設後的狀態。稍後才首次啟用的主控台——
1787
+ 例如剛開機按 `Ctrl-Alt-F3`——仍從核心預設開始;在 REPL
1788
+ 執行 `numlock()`(或 `numlock(false)`)
1789
+ 可再次將設定套用到所有主控台。提交空白或只有空格的 REPL 行,會
1790
+ 再次印出歡迎訊息及可用 `cfg` getter。載入器與
1791
+ libc 路徑內容位元組相同,但刻意使用不同 inode:
1792
+
1793
+ ```text
1794
+ /lib/ld-musl-x86_64.so.1 /lib/ld-musl-aarch64.so.1
1795
+ /lib/libc.musl-x86_64.so.1 /lib/libc.musl-aarch64.so.1
1796
+ ```
1797
+
1798
+ 對已作為 Bun 載入器的同一個 musl inode 呼叫 `dlopen`
1799
+ 會死鎖,獨立實體 libc 則可運作。它提供 `mount`、
1800
+ `waitpid`、網路呼叫與通用 `syscall` 入口,因此不需要
1801
+ 自訂 `libinit.so`。
1802
+
1803
+ `--real` 開機時,init 以 `1.1.1.1` 和
1804
+ `8.8.8.8` 初始化 `/etc/resolv.conf`,
1805
+ 作為使用者換成適合本地網路 DNS 前的初始公共解析器。硬體
1806
+ 網路在 `cfg.net` 載入已打包驅動並嘗試 DHCP
1807
+ 設定前維持停用。仍可用 `ip` 手動設定位址與路由。
1808
+
1809
+ `cfg.net` 為每個偵測到的非 loopback 介面在背景
1810
+ 啟動 DHCP,立即返回;失敗與取得逾時只記錄訊息,不中斷
1811
+ init。各客戶端設定租約後退出,不留下續租行程。重複呼叫 `cfg.net`
1812
+ 不會重複啟動仍在執行的客戶端。路由 metric 從
1813
+ 100 開始;只有第一個介面更新 DNS,若它無法取得
1814
+ 租約,init 的備援解析器仍可使用。
1815
+
1816
+ 租約到期或需要重新取得網路設定時,執行 `dhclient usb0`
1817
+ (或依介面名稱使用 `dhclient eth0`)。
1818
+ `cfg.net` 自動設定成功後,不需要再多做此步驟。
1819
+ `dhclient` 設定完成便退出;`-timeout 20`
1820
+ 將取得時間限制為 20 秒。租約不會自動續租。手動固定
1821
+ 設定請見[基本設定](#基本設定)。
1822
+
1823
+ `--real` 映像的 REPL 也提供以 getter 為基礎的 `cfg` 命名空間:
1824
+ `cfg.net`、`cfg.disk`、`cfg.power`、`cfg.sound`、`cfg.gpu` 與 `cfg.all` 讀取屬性時
1825
+ 立即執行,不需括號。`cfg.net` 載入所有已打包網路模組(包含 PHY 與匯流排支援),再讀取各 PCI、
1826
+ USB 網路裝置的 `modalias`,與 `fetch-alpine.sh` 保留
1827
+ 於 `modules.alias`
1828
+ 的 `pci:`/`usb:` 行比對,並列出介面。`cfg.disk` 載入已打包
1829
+ SATA/PATA/SCSI、NVMe/VMD 與 USB 儲存堆疊,讓磁碟與
1830
+ 分割區出現在 `/dev`,再列出 `/sys/class/block`。`cfg.all` 嘗試
1831
+ **除了 GPU 模組以外**的所有已打包模組,並遞迴載入其宣告依賴。`--real` 包含
1832
+ Intel `e1000`/`e1000e`/`igb`/`igc`、Realtek
1833
+ `r8169`、Atheros `alx`、Broadcom `tg3`、常見 USB
1834
+ 網卡,以及供 Android USB 網路共享的 `rndis_host`/`cdc_ether`
1835
+ /`cdc_ncm`/`cdc_eem`/`cdc_subset`/`zaurus`。
1836
+ `cfg.net` 無條件嘗試這些已打包網路模組。`cfg.sound` 同樣無條件嘗試
1837
+ `kernel/sound/` 下所有已打包模組,再列出 `/dev/snd`,不做硬體探測。
1838
+
1839
+ 所選核心類型有提供時,打包音效集涵蓋 QEMU ES1371/HDA、常見 PC HDA/
1840
+ HDMI 及 USB 音效。`cfg.power` 透過 `/lib/modprobe.js`
1841
+ 載入 ACPI 的 `battery`、`ac`、`button`、`thermal`
1842
+ 模組,並列出 `/sys/class/power_supply`(無電池桌機只會回報
1843
+ 沒有註冊項目)。開機時不會載入它們。PID 1 也安裝 `uncaughtException`
1844
+ /`unhandledRejection` 監聽器;若沒有,在提示中一個未處理的
1845
+ `Promise.reject()` 就會讓 Bun 退出,造成核心 panic
1846
+ (`Attempted to kill init!`)。
1847
+
1848
+ `start()` 啟動內附的 Buninu 使用者空間及 bunmsh(Bun
1849
+ Modern Shell),保留目前行程環境,同時覆寫使用者空間工作階段的
1850
+ `PATH` 與 `HOME`。
1851
+
1852
+ ### 可選的客戶端圖形加速
1853
+
1854
+ 若建置時只要省略額外要求的 GPU 模組與韌體:
1855
+
1856
+ ```sh
1857
+ bun index.js -b --real --no-gpu
1858
+ ```
1859
+
1860
+ 原有 simpledrm/fbcon/bunterm
1861
+ 路徑、音效/網路/儲存模組及其所需依賴都
1862
+ 保留。此設定作用於下載與建置,並轉送進
1863
+ Docker。直接使用 shell 腳本時,執行
1864
+ `env BUNINU_NO_GPU=1 REAL_MACHINE=1 LINUX_FLAVOR=lts ./build-uki.sh`。
1865
+ 切換此選項會使模組/韌體快取失效;省略選項(並取消設定 `BUNINU_NO_GPU`)
1866
+ 即可恢復預設 GPU 打包。已快取 APK 下載檔保留,但不放進映像。
1867
+ 這不會停用所選核心已編入的 GPU 支援。
1868
+
1869
+
1870
+ GPU 驅動會打包,但**不會由開機、`start()`、`cfg.all` 或 `cfgMod` 載入**。
1871
+ 既有 simpledrm/framebuffer 與軟體渲染 bunterm 路徑
1872
+ 仍是預設。在開啟 bunterm/fbdev 前,於 PID 1 REPL 明確讀取:
1873
+
1874
+ ```js
1875
+ cfg.gpu
1876
+ ```
1877
+
1878
+ 這是一次性的 PCI/virtio 硬體探測,不是常駐服務。它配對可用
1879
+ 驅動、載入模組依賴,並列出 `/dev/dri/renderD*`
1880
+ 與 `/dev/fb*`。個別驅動失敗會回報,但不停止 init。
1881
+ 缺少 render 節點不會被回報為成功加速:請檢查核心韌體/驅動
1882
+ 訊息;若探測是非同步,稍後再次讀取 `cfg.gpu`。若行程已持有
1883
+ `/dev/fb*` 的 fd 或 mmap,會拒絕載入 GPU 驅動。
1884
+ 先退出該 framebuffer 客戶端;GPU 接管後重新開啟,以
1885
+ 取得新的 framebuffer、解析度與像素格式。不保證一定是 `fb0`。
1886
+
1887
+ x86_64 LTS 模組集包含 Intel `i915`/`xe`、AMD `amdgpu`
1888
+ /舊版 `radeon`、NVIDIA **Nouveau** 及 VMware
1889
+ `vmwgfx`;兩種架構都要求 `virtio_gpu`。所選 Alpine 核心
1890
+ 沒有的模組會略過並在建置時註明。有 PC GPU 模組時會包含五個鎖定的 Alpine
1891
+ `linux-firmware-{i915,xe,amdgpu,radeon,nvidia}`
1892
+ 套件(下載約 151 MB)。保留韌體符號連結與目錄別名,核心直接讀取其 `.zst`
1893
+ 檔。韌體版本鎖定於 `scripts/gpu-firmware.json`;授權
1894
+ 與 WHENCE 位於 `LICENSES/linux-firmware/`。
1895
+ 請重建既有映像以加入新模組與韌體;建置會偵測舊版下載快取。
1896
+
1897
+ render 節點設為 `root:0`、權限 `0660`,供本系統 root
1898
+ 客戶端使用。非 root 客戶端請在讀取 getter 前設定數字形式的附加群組:
1899
+
1900
+ ```js
1901
+ process.env.BUNINU_RENDER_GID = "107" // 使用客戶端實際的 render 群組 ID
1902
+ cfg.gpu
1903
+ ```
1904
+
1905
+ 客戶端必須以該數字群組執行,且在 chroot/proot 內能看到實際的
1906
+ `/dev/dri` 節點與相關 `/sys`。Mesa、Vulkan
1907
+ loader/ICD 及其依賴屬於**客戶端**環境;此變更不安裝它們,也不
1908
+ 加速 CanvasKit/Land 本身。僅有 render 節點不能證明
1909
+ 硬體渲染,應確認 `vulkaninfo`/瀏覽器渲染器及可見輸出。QEMU 另需
1910
+ 加速的主機 GPU 後端(VirGL/Venus);單純 2D virtio
1911
+ GPU 不代表 3D 加速。此處不包含 NVIDIA 專有驅動、Android
1912
+ KGSL 或特定 ARM 板子的 GPU/DT/韌體啟用支援。
1913
+
1914
+ ## 目錄
1915
+
1916
+ - [快速開始](#快速開始)
1917
+ * [步驟](#步驟)
1918
+ + [直接透過套件建置](#直接透過套件建置)
1919
+ + [或從原始碼建置](#或從原始碼建置)
1920
+ + [寫入映像檔到隨身碟](#寫入映像檔到隨身碟)
1921
+ + [從隨身碟開機](#從隨身碟開機)
1922
+ * [在桌面系統建置及測試虛擬機](#在桌面系統建置及測試虛擬機)
1923
+ + [macOS](#macos)
1924
+ + [amd64 Linux](#amd64-linux)
1925
+ + [六十四位元安謀架構的差異](#六十四位元安謀架構的差異)
1926
+ + [在容器中測試主機建置流程](#在容器中測試主機建置流程)
1927
+ - [使用作業系統](#使用作業系統)
1928
+ * [基本設定](#基本設定)
1929
+ * [使用終端機](#使用終端機)
1930
+ * [使用命令殼層](#使用命令殼層)
1931
+ * [編輯器快速開始](#編輯器快速開始)
1932
+ + [jsmdcui](#jsmdcui)
1933
+ * [多工模式](#多工模式)
1934
+ + [多個虛擬主控台](#多個虛擬主控台)
1935
+ + [編輯器的窗格與終端分頁](#編輯器的窗格與終端分頁)
1936
+ - [窗格與分頁操作](#窗格與分頁操作)
1937
+ * [顯示圖片](#顯示圖片)
1938
+ * [剪貼簿](#剪貼簿)
1939
+ * [實驗性有聲影片播放](#實驗性有聲影片播放)
1940
+ * [資料與持久保存](#資料與持久保存)
1941
+ - [內建命令](#內建命令)
1942
+ * [內建瀏覽器的早期實驗支援](#內建瀏覽器的早期實驗支援)
1943
+ * [內建合成器的早期實驗支援](#內建合成器的早期實驗支援)
1944
+ * [封存工具及其他範例](#封存工具及其他範例)
1945
+ - [可選的根目錄切換與原生程式](#可選的根目錄切換與原生程式)
1946
+ * [在隔離根目錄使用瀏覽器前端](#在隔離根目錄使用瀏覽器前端)
1947
+ * [最小根檔案系統](#最小根檔案系統)
1948
+ * [使用既有根檔案系統](#使用既有根檔案系統)
1949
+ - [環境與依賴](#環境與依賴)
1950
+ * [建置環境](#建置環境)
1951
+ * [作業系統建置所需工具 (第二節)](#作業系統建置所需工具-第二節)
1952
+ * [問候範例所需工具 (第一節)](#問候範例所需工具-第一節)
1953
+ * [已退役的原生啟動程式](#已退役的原生啟動程式)
1954
+ - [舊版建置工具](#舊版建置工具)
1955
+ * [舊版直接透過套件建置](#舊版直接透過套件建置)
1956
+ * [舊版從原始碼建置](#舊版從原始碼建置)
1957
+ - [實作細節](#實作細節)
1958
+ * [第一節問候範例](#第一節問候範例)
1959
+ * [第二節作業系統與初始行程](#第二節作業系統與初始行程)
1960
+ + [建置旗標](#建置旗標)
1961
+ + [建置流程](#建置流程)
1962
+ - [流程輸入與輸出](#流程輸入與輸出)
1963
+ + [統一核心映像配置](#統一核心映像配置)
1964
+ - [統一核心映像區段](#統一核心映像區段)
1965
+ + [磁碟配置](#磁碟配置)
1966
+ + [真機開機細節](#真機開機細節)
1967
+ + [虛擬機開發](#虛擬機開發)
1968
+ - [虛擬機網路](#虛擬機網路)
1969
+ + [命令實作](#命令實作)
1970
+ + [終端機影像傳輸](#終端機影像傳輸)
1971
+ + [尚未掛載時進入腳本環境](#尚未掛載時進入腳本環境)
1972
+ + [初始化腳本的工作](#初始化腳本的工作)
1973
+ * [可選的客戶端圖形加速](#可選的客戶端圖形加速)
1974
+ - [作者](#作者)
1975
+ - [授權](#授權)
1976
+ * [內附元件授權](#內附元件授權)
1977
+
1978
+ ## 作者
1979
+
1980
+ Buninu Linux 由其使用者空間
1981
+ [Buninu](https://github.com/jjtseng93/buninu)
1982
+ 的作者 Dr. John 撰寫與維護。核心、C 函式庫、GCC 執行環境、UEFI
1983
+ stub 與 Bun 本身都是各自專案的成果;[NOTICE.md](NOTICE.md)
1984
+ 列出每個元件在此發行的精確版本、套件與 SHA-256。
1985
+
1986
+ ## 授權
1987
+
1988
+ Buninu Linux 自有作品——建置腳本、`hello/hello.c`、
1989
+ `init.js`、已退役啟動程式,以及設定與中繼資料檔案——採 MIT 授權,見
1990
+ [LICENSE](LICENSE)。`initramfs/buninu/` 下
1991
+ 的 Buninu 使用者空間也採 MIT(`initramfs/buninu/LICENSE`),
1992
+ 並附有自身的第三方聲明,列於 [NOTICE.md](NOTICE.md) 末尾。
1993
+
1994
+ 儲存庫也為每個客體架構在 `native/<arch>/lib/`
1995
+ 提交四個第三方平台二進位檔,建置的映像還會重新散布更多元件。
1996
+ 各自維持原有條款,平台
1997
+ 授權文字位於 [`LICENSES/`](LICENSES/)。
1998
+
1999
+ 建置也會下載五個以 SHA-256 鎖定的 npm 發行版,並於
2000
+ `/usr/lib/node_modules` 重新散布:`buninu-browser`、`buninu-land`、
2001
+ `@drxiaozhi/casty`、`@drxiaozhi/jspulse` 及
2002
+ `@drxiaozhi/jspinyin`。其授權與聲明檔案保留在套件目錄中。精確下載 URL 與雜湊見
2003
+ [`scripts/npm-packages.md`](scripts/npm-packages.md);
2004
+ 版本、上游來源及安裝後的聲明/原始碼位置記錄於
2005
+ [NOTICE.md](NOTICE.md#npm-applications-fetched-and-redistributed-in-the-image)。
2006
+ 本專案 MIT 授權不取代這些套件的授權。尤其
2007
+ jspulse 與瀏覽器內附的 wasmpeg/FFmpeg
2008
+ 程式碼帶有 LGPL 義務;重新散布映像時,請保留其
2009
+ 授權及提供的原始碼/重建資料。
2010
+
2011
+ ### 內附元件授權
2012
+
2013
+ | 元件 | 授權 | 位置 |
2014
+ |---|---|---|
2015
+ | musl(`ld-musl-x86_64.so.1`、`libc.musl-x86_64.so.1` 及 `aarch64` 對應組合) | MIT | 已提交 |
2016
+ | GCC 執行環境(`libgcc_s.so.1`、`libstdc++.so.6`) | GPL-3.0-or-later,附 GCC Runtime Library Exception | 已提交 |
2017
+ | Linux 核心及網路、儲存、xHCI、USB、HID 模組 | GPL-2.0-only,附 Linux syscall note | 僅映像內 |
2018
+ | systemd EFI stub | LGPL-2.1-or-later | 僅映像內 |
2019
+ | Bun | MIT,以及靜態連結元件的各自授權 | 僅映像內 |
2020
+ | buninu-browser | 自有程式碼採 MIT;內附元件各有授權 | npm 下載 → 映像 |
2021
+ | buninu-land | 自有程式碼採 MIT;內附元件保留各自授權與聲明 | npm 下載 → 映像 |
2022
+ | wasmpeg/FFmpeg(`@wasmpeg/cpu` 1.0.1,內附於 buninu-browser) | LGPL-2.1-or-later,另附元件聲明;保留原始碼封存檔與重建文件 | 瀏覽器套件 → 映像 |
2023
+ | `@drxiaozhi/casty` | MIT | npm 下載 → 映像 |
2024
+ | `@drxiaozhi/jspulse` | LGPL-2.1-or-later,另附元件聲明 | npm 下載 → 映像 |
2025
+ | `@drxiaozhi/jspinyin` | MIT;hanzipinyin 素材採 Unlicense | npm 下載 → 映像 |
2026
+ | CanvasKit 0.41.1(`initramfs/lib/canvaskit/`,編譯成 WebAssembly 的 Skia) | BSD-3-Clause(`LICENSES/BSD-3-Clause-Skia.txt`) | 已提交 |
2027
+ | xterm.js 6.0.0 無頭核心與 unicode-graphemes 附加元件(`initramfs/lib/xterm/`);`initramfs/lib/bunterm/glyphs.js` 中的框線形狀表 | MIT(`LICENSES/MIT-xterm.js.txt`) | 已提交 |
2028
+ | DejaVu Sans Mono(`initramfs/usr/share/fonts/DejaVuSansMono*.ttf`) | Bitstream Vera(`LICENSES/Bitstream-Vera.txt`) | 已提交 |
2029
+ | Noto Sans CJK、Noto Color Emoji(含 Flags)、Noto Sans Symbols(`initramfs/usr/share/fonts/Noto*`) | SIL OFL 1.1(`LICENSES/OFL-1.1.txt`) | 已提交 |
2030
+ | Roboto(`initramfs/usr/share/fonts/Roboto-Regular.ttf`) | Apache-2.0(`LICENSES/Apache-2.0.txt`) | 已提交 |
2031
+
2032
+ 有個元件值得直接指出,而不是留待讀者自行發現:兩個 GCC 執行環境函式庫採
2033
+ **GPL-3.0,附 GCC Runtime Library Exception**
2034
+ (Buninu 的 `apps/musl-la/` 所提交、映像也一併攜帶
2035
+ 的 aarch64 `libgcc_s.so.1`/`libstdc++.so.6`
2036
+ 也是如此)。正是這項例外允許它們與 MIT 程式碼一同發行,所以此處不
2037
+ 改變 Buninu Linux 自身的條款;但若組織會篩查 GPL,會找到的
2038
+ 就是這些元件。[NOTICE.md](NOTICE.md)
2039
+ 記錄各元件的精確 Alpine 建置、作為對應原始碼的鎖定
2040
+ aports 提交、套件 SHA-256,以及選定解出檔案的 SHA
2041
+ -256。