{"id":13590267,"url":"https://github.com/akkartik/mu","last_synced_at":"2025-05-14T16:13:11.395Z","repository":{"id":23668745,"uuid":"27039826","full_name":"akkartik/mu","owner":"akkartik","description":"Soul of a tiny new machine. More thorough tests → More comprehensible and rewrite-friendly software → More resilient society.","archived":false,"fork":false,"pushed_at":"2024-10-17T16:39:39.000Z","size":92264,"stargazers_count":1402,"open_issues_count":5,"forks_count":45,"subscribers_count":40,"default_branch":"main","last_synced_at":"2025-04-05T19:08:04.544Z","etag":null,"topics":["linux","machine-code","programming-literacy","unit-tested","white-box-testing","x86"],"latest_commit_sha":null,"homepage":"http://akkartik.name/akkartik-convivial-20200607.pdf","language":"Assembly","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/akkartik.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-11-23T17:05:30.000Z","updated_at":"2025-04-03T08:38:10.000Z","dependencies_parsed_at":"2024-01-18T23:09:12.863Z","dependency_job_id":"c7b0fa13-ac8e-4a6c-ba5d-e7bfb04e64ac","html_url":"https://github.com/akkartik/mu","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akkartik%2Fmu","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akkartik%2Fmu/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akkartik%2Fmu/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akkartik%2Fmu/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/akkartik","download_url":"https://codeload.github.com/akkartik/mu/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248631670,"owners_count":21136554,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["linux","machine-code","programming-literacy","unit-tested","white-box-testing","x86"],"created_at":"2024-08-01T16:00:42.551Z","updated_at":"2025-04-12T20:40:24.517Z","avatar_url":"https://github.com/akkartik.png","language":"Assembly","funding_links":[],"categories":["Assembly","Other"],"sub_categories":[],"readme":"# Mu: a human-scale computer\n\nMu is a minimal-dependency hobbyist computing stack (everything above the\nprocessor).\n\nMu is not designed to operate in large clusters providing services for\nmillions of people. Mu is designed for _you_, to run one computer. (Or a few.)\nRunning the code you want to run, and nothing else.\n\nHere's the Mu computer running [Conway's Game of Life](https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life).\n\n```sh\ngit clone https://github.com/akkartik/mu\ncd mu\n./translate apps/life.mu  # emit a bootable code.img\nqemu-system-i386 code.img\n```\n\n![screenshot of Game of Life running on the Mu computer](html/life.png)\n\n([Colorized sources.](http://akkartik.github.io/mu/html/apps/life.mu.html)\nThis is memory-safe code, and most statements map to a single instruction of\nmachine code.)\n\nRather than start from some syntax and introduce layers of translation to\nimplement it, Mu starts from the processor's instruction set and tries to get\nto _some_ safe and clear syntax with as few layers of translation as possible.\nThe emphasis is on internal consistency at any point in time rather than\ncompatibility with the past. ([More details.](http://akkartik.name/akkartik-convivial-20200607.pdf))\n\nTests are a key mechanism here for creating a computer that others can make\ntheir own. I want to encourage a style of active and interactive reading with\nMu. If something doesn't make sense, try changing it and see what tests break.\nAny breaking change should cause a failure in some well-named test somewhere.\n\nMu requires a 32-bit x86 processor. It supports a short list of generic\nhardware. There's no networking support yet. Development has slowed, but I\nstill care about it. Feedback, bug reports and other forms of contribution\ncontinue to be appreciated.\n\n_Mu in the press_\n\n* [Qemu Advent Calendar 2023](http://qemu-advent-calendar.org/2023/) (day 4)\n* [Advent of v86](https://copy.sh/v86/advent/2023/?day=4)\n\n## Goals\n\nIn priority order:\n\n- [Reward curiosity.](http://akkartik.name/about)\n  - Easy to build, easy to run. [Minimal dependencies](https://news.ycombinator.com/item?id=16882140#16882555),\n    so that installation is always painless.\n  - All design decisions comprehensible to a single individual. (On demand.)\n  - All design decisions comprehensible without needing to talk to anyone.\n    (I always love talking to you, but I try hard to make myself redundant.)\n  - [A globally comprehensible _codebase_ rather than locally clean code.](http://akkartik.name/post/readable-bad)\n  - Clear error messages over expressive syntax.\n- Safe.\n  - Thorough test coverage. If you break something you should immediately see\n    an error message.\n  - Memory leaks over memory corruption.\n- Teach the computer bottom-up.\n\nThorough test coverage in particular deserves some elaboration. It implies\nthat any manual test should be easy to turn into a reproducible automated\ntest. Mu has some unconventional methods for providing this guarantee. It\nexposes testable interfaces for hardware using dependency injection so that\ntests can run on -- and make assertions against -- fake hardware. It also\nperforms [automated white-box testing](http://akkartik.name/post/tracing-tests)\nwhich enables robust tests for performance, concurrency, fault-tolerance, etc.\n\n## Non-goals\n\n- Speed. Staying close to machine code should naturally keep Mu fast enough.\n- Efficiency. Controlling the number of abstractions should naturally keep Mu\n  using far less than the gigabytes of memory modern computers have.\n- Portability. Mu will run on any computer as long as it's x86. I will\n  enthusiastically contribute to support for other processors -- in separate\n  forks. Readers shouldn't have to think about processors they don't have.\n- Compatibility. The goal is to get off mainstream stacks, not to perpetuate\n  them. Sometimes the right long-term solution is to [bump the major version number](http://akkartik.name/post/versioning).\n- Syntax. Mu code is meant to be comprehended by [running, not just reading](http://akkartik.name/post/comprehension).\n  It will always be just a thin memory-safe veneer over machine code.\n  I don't know how to make higher-level notations both fast and\n  comprehensible, so they are likely to remain slow and comprehensible, useful\n  for prototyping but invariably needing to be rewritten in statements that\n  map 1:1 with machine code. The goal of a prototype should be a risk-free\n  rewrite, thanks to tests that capture all the details of lessons learned.\n\n## Toolchain\n\nThe Mu stack consists of:\n- the Mu type-safe and memory-safe language;\n- SubX, an unsafe notation for a subset of x86 machine code; and\n- _bare_ SubX, a more rudimentary form of SubX without certain syntax sugar.\n\nAll Mu programs get translated through these layers into tiny zero-dependency\nbinaries that run natively. The translators for most levels are built out of\nlower levels. The translator from Mu to SubX is written in SubX, and the\ntranslator from SubX to bare SubX is built in bare SubX. There is also an\nemulator for Mu's supported subset of x86, that's useful for [debugging SubX\nprograms](linux/subx_debugging.md).\n\nMu programs build natively either on Linux or on Windows using [WSL 2](https://docs.microsoft.com/en-us/windows/wsl/install-win10).\nFor Macs and other Unix-like systems, use the (much slower) emulator:\n\n```sh\n./translate_emulated apps/ex2.mu  # 2-5 minutes to emit code.img\n```\n\nMu programs can be written for two very different environments:\n\n* At the top-level, Mu programs emit a bootable image that runs without an OS\n  (under emulation; I haven't tested on native hardware yet). There's rudimentary\n  support for some core peripherals: a 1024x768 screen, a keyboard with some\n  key-combinations, a PS/2 mouse that must be polled, a slow ATA disk drive.\n  No hardware acceleration, no virtual memory, no process separation, no\n  multi-tasking, no network. Boot always runs all tests, and only gets to\n  `main` if all tests pass.\n\n* The top-level is built using tools created under the `linux/` sub-directory.\n  This sub-directory contains an entirely separate set of libraries intended\n  for building programs that run with just a Linux kernel, reading from stdin\n  and writing to stdout. The Mu compiler is such a program, at `linux/mu.subx`.\n  Individual programs typically run tests if given a command-line argument\n  called `test`.\n\nThe largest program built in Mu today is its prototyping environment for\nwriting slow, interpreted programs in a Lisp-based high-level language.\n\n![screenshot of the Mu shell](html/20210624-shell.png)\n\n(For more details, see [the `shell/` directory.](https://github.com/akkartik/mu/tree/main/shell#readme))\n\nWhile I currently focus on programs without an OS, the `linux/` sub-directory\nis fairly ergonomic. There's a couple of dozen example programs to try out\nthere. It is likely to be the option for a network stack in the foreseeable\nfuture; I have no idea how to interact on the network without Linux.\n\n## Syntax\n\nThe entire stack shares certain properties and conventions. Programs consist\nof functions and functions consist of statements, each performing a single\noperation. Operands to statements are always variables or constants. You can't\nperform `a + b*c` in a single statement; you have to break it up into two.\nVariables can live in memory or in registers. Registers must be explicitly\nspecified. There are some shared lexical rules. Comments always start with\n'#'. Numbers are always written in hex. Many terms can have context-dependent\n_metadata_ attached after '/'.\n\nHere's an example program in Mu:\n\n\u003cimg alt='ex2.mu' src='html/ex2.mu.png' width='400px'\u003e\n\nMore resources on Mu:\n\n* [Mu Syntax reference](mu.md)\n\n* [Library reference.](vocabulary.md) Mu programs can transparently call\n  low-level functions written in SubX.\n\nHere's an example program in SubX:\n\n```sh\n== code\nEntry:\n  # ebx = 1\n  bb/copy-to-ebx  1/imm32\n  # increment ebx\n  43/increment-ebx\n  # exit(ebx)\n  e8/call  syscall_exit/disp32\n```\n\nMore resources on SubX:\n\n* [SubX syntax reference](subx.md)\n\n* [Some starter exercises for learning SubX](https://github.com/akkartik/mu/pulls)\n  (labelled `hello`). Feel free to [ping me](mailto:ak@akkartik.com) with any\n  questions.\n\n* The [list of x86 opcodes](subx_opcodes) supported in SubX: `linux/bootstrap/bootstrap help opcodes`.\n\n* [Some tips for debugging SubX programs.](linux/subx_debugging.md)\n\n## Mirrors and Forks\n\nUpdates to Mu can be downloaded from the following mirrors:\n* https://github.com/akkartik/mu\n* https://repo.or.cz/mu.git\n* https://codeberg.org/akkartik/mu\n* https://tildegit.org/akkartik/mu\n* https://git.tilde.institute/akkartik/mu\n* https://git.sr.ht/~akkartik/mu\n\nForks of Mu are encouraged. If you don't like something about this repo, feel\nfree to make a fork. If you show it to me, I'll link to it here. I might even\npull features upstream!\n\n- [uCISC](https://github.com/grokthis/ucisc): a 16-bit processor being\n  designed from scratch by [Robert Butler](https://www.youtube.com/channel/UCh4OpfF7T7UtezGejRTLxCw)\n  and programmed with a SubX-like syntax.\n- [subv](https://git.s-ol.nu/subv): experimental SubX-like syntax by [s-ol\n  bekic](https://mmm.s-ol.nu) for the RISC-V instruction set.\n- [mu-x86\\_64](https://git.sr.ht/~akkartik/mu-x86_64): experimental fork for\n  64-bit x86 in collaboration with [Max Bernstein](https://bernsteinbear.com).\n  It's brought up a few concrete open problems that I don't have good solutions\n  for yet.\n- [mu-normie](https://git.sr.ht/~akkartik/mu-normie): with a more standard\n  build system for the `linux/bootstrap/` directory that organizes the repo by\n  header files and compilation units. Stays in sync with this repo.\n\n## Desiderata\n\nIf you're still reading, here are some more things to check out:\n\n- [A slow guided tour of Mu.](tutorial/index.md)\n\n- [How to get your text editor set up for Mu and SubX programs.](editor/editor.md)\n\n- [Some videos demonstrating Mu programs and features.](https://www.youtube.com/watch?v=SZBAXgXvzqE\u0026list=PLxyWgjDVNN4qtMcoR7JRcYPbrwMdnGNsS)\n\n- [A summary](mu_instructions) of how the Mu compiler translates statements\n  to SubX. Most Mu statements map to a single x86 instruction.\n  ([colorized version](http://akkartik.github.io/mu/html/mu_instructions.html))\n\n- A prototype live-updating programming environment for a postfix language\n  that I might work on again one day:\n\n  ```sh\n  cd linux\n  ./translate tile/*.mu\n  ./a.elf screen\n  ```\n\n- Previous prototypes: [mu0](https://github.com/akkartik/mu0), [mu1](https://github.com/akkartik/mu1).\n\n## Credits\n\nMu builds on many ideas that have come before, especially:\n\n- [Peter Naur](http://akkartik.name/naur.pdf) for articulating the paramount\n  problem of programming: communicating a codebase to others;\n- [Christopher Alexander](http://www.amazon.com/Notes-Synthesis-Form-Harvard-Paperbacks/dp/0674627512)\n  and [Richard Gabriel](https://www.dreamsongs.com/Files/PatternsOfSoftware.pdf) for\n  the intellectual tools for reasoning about the higher order design of a\n  codebase;\n- [David Parnas](http://www.cs.umd.edu/class/spring2003/cmsc838p/Design/criteria.pdf)\n  and others for highlighting the value of separating concerns and stepwise\n  refinement;\n- The folklore of debugging by print and the trace facility in many Lisp\n  systems;\n- Automated tests for showing the value of developing programs inside an\n  elaborate harness;\n\nOn a more tactical level, this project has made progress in a series of bursts\nas I discovered the following resources. In autobiographical order, with no\nclaims of completeness:\n- [\u0026ldquo;Bootstrapping a compiler from nothing\u0026rdquo;](http://web.archive.org/web/20061108010907/http://www.rano.org/bcompiler.html) by Edmund Grimley-Evans.\n- [StoneKnifeForth](https://github.com/kragen/stoneknifeforth) by [Kragen Sitaker](http://canonical.org/~kragen),\n  including [a tiny sketch of an ELF loader](https://github.com/kragen/stoneknifeforth/blob/master/386.c).\n- [\u0026ldquo;Creating tiny ELF executables\u0026rdquo;](https://www.muppetlabs.com/~breadbox/software/tiny/teensy.html) by Brian Raiter.\n- [Single-page cheatsheet for the x86 ISA](https://net.cs.uni-bonn.de/fileadmin/user_upload/plohmann/x86_opcode_structure_and_instruction_overview.pdf)\n  by Daniel Plohmann ([cached local copy](https://github.com/akkartik/mu/blob/main/cheatsheet.pdf))\n- [Minimal Linux Live](http://minimal.linux-bg.org) for teaching how to create\n  a bootable disk image using the syslinux bootloader.\n- [\u0026ldquo;Writing a bootloader from scratch\u0026rdquo;](https://www.cs.bham.ac.uk/~exr/lectures/opsys/10_11/lectures/os-dev.pdf)\n  by Nick Blundell.\n- Wikipedia on BIOS interfaces: [Int 10h](https://en.wikipedia.org/wiki/INT_10H), [Int 13h](https://en.wikipedia.org/wiki/INT_13H).\n- [Some tips on programming bootloaders](https://stackoverflow.com/questions/43786251/int-13h-42h-doesnt-load-anything-in-bochs/43787939#43787939)\n  by Michael Petch.\n- [xv6, the port of Unix Version 6 to x86 processors](https://github.com/mit-pdos/xv6-public)\n- Some tips on handling keyboard interrupts by [Alex Dzyoba](https://alex.dzyoba.com/blog/os-interrupts)\n  and [Michael Petch](https://stackoverflow.com/questions/37618111/keyboard-irq-within-an-x86-kernel).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fakkartik%2Fmu","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fakkartik%2Fmu","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fakkartik%2Fmu/lists"}