much love
[mu.git] / README.md
blob2fc96b557d0e54ac615a6eea5d2871da0deed1e5
1 # Mu: a human-scale computer
3 Mu is a minimal-dependency hobbyist computing stack (everything above the
4 processor).
6 Mu is not designed to operate in large clusters providing services for
7 millions of people. Mu is designed for _you_, to run one computer. (Or a few.)
8 Running the code you want to run, and nothing else.
10 Here's the Mu computer running [Conway's Game of Life](https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life).
12 ```sh
13 git clone https://github.com/akkartik/mu
14 cd mu
15 ./translate apps/life.mu  # emit a bootable code.img
16 qemu-system-i386 code.img
17 ```
19 ![screenshot of Game of Life running on the Mu computer](html/life.png)
21 ([Colorized sources.](http://akkartik.github.io/mu/html/apps/life.mu.html)
22 This is memory-safe code, and most statements map to a single instruction of
23 machine code.)
25 Rather than start from some syntax and introduce layers of translation to
26 implement it, Mu starts from the processor's instruction set and tries to get
27 to _some_ safe and clear syntax with as few layers of translation as possible.
28 The emphasis is on internal consistency at any point in time rather than
29 compatibility with the past. ([More details.](http://akkartik.name/akkartik-convivial-20200607.pdf))
31 Tests are a key mechanism here for creating a computer that others can make
32 their own. I want to encourage a style of active and interactive reading with
33 Mu. If something doesn't make sense, try changing it and see what tests break.
34 Any breaking change should cause a failure in some well-named test somewhere.
36 Mu requires a 32-bit x86 processor. It supports a short list of generic
37 hardware. There's no networking support yet. Development has slowed, but I
38 still care about it. Feedback, bug reports and other forms of contribution
39 continue to be appreciated.
41 _Mu in the press_
43 * [Qemu Advent Calendar 2023](http://qemu-advent-calendar.org/2023/) (day 4)
44 * [Advent of v86](https://copy.sh/v86/advent/2023/?day=4)
46 ## Goals
48 In priority order:
50 - [Reward curiosity.](http://akkartik.name/about)
51   - Easy to build, easy to run. [Minimal dependencies](https://news.ycombinator.com/item?id=16882140#16882555),
52     so that installation is always painless.
53   - All design decisions comprehensible to a single individual. (On demand.)
54   - All design decisions comprehensible without needing to talk to anyone.
55     (I always love talking to you, but I try hard to make myself redundant.)
56   - [A globally comprehensible _codebase_ rather than locally clean code.](http://akkartik.name/post/readable-bad)
57   - Clear error messages over expressive syntax.
58 - Safe.
59   - Thorough test coverage. If you break something you should immediately see
60     an error message.
61   - Memory leaks over memory corruption.
62 - Teach the computer bottom-up.
64 Thorough test coverage in particular deserves some elaboration. It implies
65 that any manual test should be easy to turn into a reproducible automated
66 test. Mu has some unconventional methods for providing this guarantee. It
67 exposes testable interfaces for hardware using dependency injection so that
68 tests can run on -- and make assertions against -- fake hardware. It also
69 performs [automated white-box testing](http://akkartik.name/post/tracing-tests)
70 which enables robust tests for performance, concurrency, fault-tolerance, etc.
72 ## Non-goals
74 - Speed. Staying close to machine code should naturally keep Mu fast enough.
75 - Efficiency. Controlling the number of abstractions should naturally keep Mu
76   using far less than the gigabytes of memory modern computers have.
77 - Portability. Mu will run on any computer as long as it's x86. I will
78   enthusiastically contribute to support for other processors -- in separate
79   forks. Readers shouldn't have to think about processors they don't have.
80 - Compatibility. The goal is to get off mainstream stacks, not to perpetuate
81   them. Sometimes the right long-term solution is to [bump the major version number](http://akkartik.name/post/versioning).
82 - Syntax. Mu code is meant to be comprehended by [running, not just reading](http://akkartik.name/post/comprehension).
83   It will always be just a thin memory-safe veneer over machine code.
84   I don't know how to make higher-level notations both fast and
85   comprehensible, so they are likely to remain slow and comprehensible, useful
86   for prototyping but invariably needing to be rewritten in statements that
87   map 1:1 with machine code. The goal of a prototype should be a risk-free
88   rewrite, thanks to tests that capture all the details of lessons learned.
90 ## Toolchain
92 The Mu stack consists of:
93 - the Mu type-safe and memory-safe language;
94 - SubX, an unsafe notation for a subset of x86 machine code; and
95 - _bare_ SubX, a more rudimentary form of SubX without certain syntax sugar.
97 All Mu programs get translated through these layers into tiny zero-dependency
98 binaries that run natively. The translators for most levels are built out of
99 lower levels. The translator from Mu to SubX is written in SubX, and the
100 translator from SubX to bare SubX is built in bare SubX. There is also an
101 emulator for Mu's supported subset of x86, that's useful for [debugging SubX
102 programs](linux/subx_debugging.md).
104 Mu programs build natively either on Linux or on Windows using [WSL 2](https://docs.microsoft.com/en-us/windows/wsl/install-win10).
105 For Macs and other Unix-like systems, use the (much slower) emulator:
107 ```sh
108 ./translate_emulated apps/ex2.mu  # 2-5 minutes to emit code.img
111 Mu programs can be written for two very different environments:
113 * At the top-level, Mu programs emit a bootable image that runs without an OS
114   (under emulation; I haven't tested on native hardware yet). There's rudimentary
115   support for some core peripherals: a 1024x768 screen, a keyboard with some
116   key-combinations, a PS/2 mouse that must be polled, a slow ATA disk drive.
117   No hardware acceleration, no virtual memory, no process separation, no
118   multi-tasking, no network. Boot always runs all tests, and only gets to
119   `main` if all tests pass.
121 * The top-level is built using tools created under the `linux/` sub-directory.
122   This sub-directory contains an entirely separate set of libraries intended
123   for building programs that run with just a Linux kernel, reading from stdin
124   and writing to stdout. The Mu compiler is such a program, at `linux/mu.subx`.
125   Individual programs typically run tests if given a command-line argument
126   called `test`.
128 The largest program built in Mu today is its prototyping environment for
129 writing slow, interpreted programs in a Lisp-based high-level language.
131 ![screenshot of the Mu shell](html/20210624-shell.png)
133 (For more details, see [the `shell/` directory.](https://github.com/akkartik/mu/tree/main/shell#readme))
135 While I currently focus on programs without an OS, the `linux/` sub-directory
136 is fairly ergonomic. There's a couple of dozen example programs to try out
137 there. It is likely to be the option for a network stack in the foreseeable
138 future; I have no idea how to interact on the network without Linux.
140 ## Syntax
142 The entire stack shares certain properties and conventions. Programs consist
143 of functions and functions consist of statements, each performing a single
144 operation. Operands to statements are always variables or constants. You can't
145 perform `a + b*c` in a single statement; you have to break it up into two.
146 Variables can live in memory or in registers. Registers must be explicitly
147 specified. There are some shared lexical rules. Comments always start with
148 '#'. Numbers are always written in hex. Many terms can have context-dependent
149 _metadata_ attached after '/'.
151 Here's an example program in Mu:
153 <img alt='ex2.mu' src='html/ex2.mu.png' width='400px'>
155 More resources on Mu:
157 * [Mu Syntax reference](mu.md)
159 * [Library reference.](vocabulary.md) Mu programs can transparently call
160   low-level functions written in SubX.
162 Here's an example program in SubX:
164 ```sh
165 == code
166 Entry:
167   # ebx = 1
168   bb/copy-to-ebx  1/imm32
169   # increment ebx
170   43/increment-ebx
171   # exit(ebx)
172   e8/call  syscall_exit/disp32
175 More resources on SubX:
177 * [SubX syntax reference](subx.md)
179 * [Some starter exercises for learning SubX](https://github.com/akkartik/mu/pulls)
180   (labelled `hello`). Feel free to [ping me](mailto:ak@akkartik.com) with any
181   questions.
183 * The [list of x86 opcodes](subx_opcodes) supported in SubX: `linux/bootstrap/bootstrap help opcodes`.
185 * [Some tips for debugging SubX programs.](linux/subx_debugging.md)
187 ## Mirrors and Forks
189 Updates to Mu can be downloaded from the following mirrors:
190 * https://github.com/akkartik/mu
191 * https://repo.or.cz/mu.git
192 * https://codeberg.org/akkartik/mu
193 * https://tildegit.org/akkartik/mu
194 * https://git.tilde.institute/akkartik/mu
195 * https://git.sr.ht/~akkartik/mu
197 Forks of Mu are encouraged. If you don't like something about this repo, feel
198 free to make a fork. If you show it to me, I'll link to it here. I might even
199 pull features upstream!
201 - [uCISC](https://github.com/grokthis/ucisc): a 16-bit processor being
202   designed from scratch by [Robert Butler](https://www.youtube.com/channel/UCh4OpfF7T7UtezGejRTLxCw)
203   and programmed with a SubX-like syntax.
204 - [subv](https://git.s-ol.nu/subv): experimental SubX-like syntax by [s-ol
205   bekic](https://mmm.s-ol.nu) for the RISC-V instruction set.
206 - [mu-x86\_64](https://git.sr.ht/~akkartik/mu-x86_64): experimental fork for
207   64-bit x86 in collaboration with [Max Bernstein](https://bernsteinbear.com).
208   It's brought up a few concrete open problems that I don't have good solutions
209   for yet.
210 - [mu-normie](https://git.sr.ht/~akkartik/mu-normie): with a more standard
211   build system for the `linux/bootstrap/` directory that organizes the repo by
212   header files and compilation units. Stays in sync with this repo.
214 ## Desiderata
216 If you're still reading, here are some more things to check out:
218 - [A slow guided tour of Mu.](tutorial/index.md)
220 - [How to get your text editor set up for Mu and SubX programs.](editor/editor.md)
222 - [Some videos demonstrating Mu programs and features.](https://www.youtube.com/watch?v=SZBAXgXvzqE&list=PLxyWgjDVNN4qtMcoR7JRcYPbrwMdnGNsS)
224 - [A summary](mu_instructions) of how the Mu compiler translates statements
225   to SubX. Most Mu statements map to a single x86 instruction.
226   ([colorized version](http://akkartik.github.io/mu/html/mu_instructions.html))
228 - A prototype live-updating programming environment for a postfix language
229   that I might work on again one day:
231   ```sh
232   cd linux
233   ./translate tile/*.mu
234   ./a.elf screen
235   ```
237 - Previous prototypes: [mu0](https://github.com/akkartik/mu0), [mu1](https://github.com/akkartik/mu1).
239 ## Credits
241 Mu builds on many ideas that have come before, especially:
243 - [Peter Naur](http://akkartik.name/naur.pdf) for articulating the paramount
244   problem of programming: communicating a codebase to others;
245 - [Christopher Alexander](http://www.amazon.com/Notes-Synthesis-Form-Harvard-Paperbacks/dp/0674627512)
246   and [Richard Gabriel](https://www.dreamsongs.com/Files/PatternsOfSoftware.pdf) for
247   the intellectual tools for reasoning about the higher order design of a
248   codebase;
249 - [David Parnas](http://www.cs.umd.edu/class/spring2003/cmsc838p/Design/criteria.pdf)
250   and others for highlighting the value of separating concerns and stepwise
251   refinement;
252 - The folklore of debugging by print and the trace facility in many Lisp
253   systems;
254 - Automated tests for showing the value of developing programs inside an
255   elaborate harness;
257 On a more tactical level, this project has made progress in a series of bursts
258 as I discovered the following resources. In autobiographical order, with no
259 claims of completeness:
260 - [&ldquo;Bootstrapping a compiler from nothing&rdquo;](http://web.archive.org/web/20061108010907/http://www.rano.org/bcompiler.html) by Edmund Grimley-Evans.
261 - [StoneKnifeForth](https://github.com/kragen/stoneknifeforth) by [Kragen Sitaker](http://canonical.org/~kragen),
262   including [a tiny sketch of an ELF loader](https://github.com/kragen/stoneknifeforth/blob/master/386.c).
263 - [&ldquo;Creating tiny ELF executables&rdquo;](https://www.muppetlabs.com/~breadbox/software/tiny/teensy.html) by Brian Raiter.
264 - [Single-page cheatsheet for the x86 ISA](https://net.cs.uni-bonn.de/fileadmin/user_upload/plohmann/x86_opcode_structure_and_instruction_overview.pdf)
265   by Daniel Plohmann ([cached local copy](https://github.com/akkartik/mu/blob/main/cheatsheet.pdf))
266 - [Minimal Linux Live](http://minimal.linux-bg.org) for teaching how to create
267   a bootable disk image using the syslinux bootloader.
268 - [&ldquo;Writing a bootloader from scratch&rdquo;](https://www.cs.bham.ac.uk/~exr/lectures/opsys/10_11/lectures/os-dev.pdf)
269   by Nick Blundell.
270 - Wikipedia on BIOS interfaces: [Int 10h](https://en.wikipedia.org/wiki/INT_10H), [Int 13h](https://en.wikipedia.org/wiki/INT_13H).
271 - [Some tips on programming bootloaders](https://stackoverflow.com/questions/43786251/int-13h-42h-doesnt-load-anything-in-bochs/43787939#43787939)
272   by Michael Petch.
273 - [xv6, the port of Unix Version 6 to x86 processors](https://github.com/mit-pdos/xv6-public)
274 - Some tips on handling keyboard interrupts by [Alex Dzyoba](https://alex.dzyoba.com/blog/os-interrupts)
275   and [Michael Petch](https://stackoverflow.com/questions/37618111/keyboard-irq-within-an-x86-kernel).