Soul of a tiny new machine. More thorough tests → More comprehensible and rewrite-friendly software → More resilient society.
Go to file
Kartik Agaram 90b374622c 6690 2020-07-30 21:39:19 -07:00
apps 6687 - stream-empty? and stream-full? 2020-07-30 19:34:29 -07:00
archive 6206 2020-04-17 01:33:51 -07:00
atom 5868 2020-01-02 12:27:35 -08:00
html 6685 2020-07-29 22:04:13 -07:00
prototypes 6679 2020-07-25 20:53:47 -07:00
tools 6674 2020-07-25 15:35:43 -07:00
.gitattributes 6690 2020-07-30 21:39:19 -07:00
.travis.yml 5914 2020-01-21 00:46:48 -08:00
000organization.cc 5704 2019-10-19 14:44:54 -07:00
001help.cc 6200 - --dump is not needed for incremental traces 2020-04-09 00:56:32 -07:00
002test.cc 5873 2020-01-02 15:11:10 -08:00
003trace.cc mu.subx: 6 failing tests remaining 2020-05-22 14:45:54 -07:00
003trace.test.cc 5485 - promote SubX to top-level 2019-07-27 17:47:59 -07:00
010vm.cc 6397 2020-05-24 22:43:18 -07:00
011run.cc 6207 - tweaks while creating a video 2020-04-19 09:32:46 -07:00
012elf.cc Raise an error if too few arguments are provided 2019-10-22 19:28:12 -07:00
013direct_addressing.cc 6090 - new instruction: multiply by immediate 2020-03-06 18:34:27 -08:00
014indirect_addressing.cc 5983 - fix an emulator bounds-check bug 2020-02-05 14:57:52 -08:00
015immediate_addressing.cc 6090 - new instruction: multiply by immediate 2020-03-06 18:34:27 -08:00
016index_addressing.cc 5485 - promote SubX to top-level 2019-07-27 17:47:59 -07:00
017jump_disp8.cc 6088 - start using setCC instructions 2020-03-06 17:42:17 -08:00
018jump_disp32.cc 6478 2020-06-05 22:04:02 -07:00
019functions.cc 5485 - promote SubX to top-level 2019-07-27 17:47:59 -07:00
020syscalls.cc 6604 - new app 2020-07-01 16:47:20 -07:00
021byte_addressing.cc 6095 2020-03-07 18:32:36 -08:00
022div.cc 5485 - promote SubX to top-level 2019-07-27 17:47:59 -07:00
030translate.cc 6397 2020-05-24 22:43:18 -07:00
031transforms.cc 5863 2020-01-02 01:28:24 -08:00
032operands.cc 6397 2020-05-24 22:43:18 -07:00
033check_operands.cc 6090 - new instruction: multiply by immediate 2020-03-06 18:34:27 -08:00
034check_operand_bounds.cc 5670 2019-09-19 15:26:24 -07:00
035compute_segment_address.cc 5892 2020-01-14 01:52:54 -08:00
036labels.cc 5892 2020-01-14 01:52:54 -08:00
037global_variables.cc 5892 2020-01-14 01:52:54 -08:00
038literal_strings.cc 6397 2020-05-24 22:43:18 -07:00
039debug.cc 6123 - runtime helper for initializing arrays 2020-03-11 17:21:59 -07:00
040tests.cc 6397 2020-05-24 22:43:18 -07:00
100.txt 6612 - reorganize layers 2020-07-05 12:13:28 -07:00
101_write.subx 6612 - reorganize layers 2020-07-05 12:13:28 -07:00
102test.subx 6612 - reorganize layers 2020-07-05 12:13:28 -07:00
103kernel-string-equal.subx 6627 2020-07-10 21:08:26 -07:00
104new-segment.subx 6612 - reorganize layers 2020-07-05 12:13:28 -07:00
105string-equal.subx 6627 2020-07-10 21:08:26 -07:00
106stream.subx 6612 - reorganize layers 2020-07-05 12:13:28 -07:00
107trace.subx 6612 - reorganize layers 2020-07-05 12:13:28 -07:00
108write.subx 6612 - reorganize layers 2020-07-05 12:13:28 -07:00
109stream-equal.subx 6627 2020-07-10 21:08:26 -07:00
110stop.subx 6612 - reorganize layers 2020-07-05 12:13:28 -07:00
111read.subx 6612 - reorganize layers 2020-07-05 12:13:28 -07:00
112read-byte.subx 6632 2020-07-11 00:11:39 -07:00
113write-stream.subx 6612 - reorganize layers 2020-07-05 12:13:28 -07:00
114error.subx 6612 - reorganize layers 2020-07-05 12:13:28 -07:00
115write-byte.subx 6612 - reorganize layers 2020-07-05 12:13:28 -07:00
116write-buffered.subx 6612 - reorganize layers 2020-07-05 12:13:28 -07:00
117write-int-hex.subx 6612 - reorganize layers 2020-07-05 12:13:28 -07:00
118parse-hex.subx 6627 2020-07-10 21:08:26 -07:00
119error-byte.subx 6612 - reorganize layers 2020-07-05 12:13:28 -07:00
120allocate.subx 6659 2020-07-18 19:33:39 -07:00
121new-stream.subx 6612 - reorganize layers 2020-07-05 12:13:28 -07:00
122read-line.subx 6612 - reorganize layers 2020-07-05 12:13:28 -07:00
123slice.subx 6627 2020-07-10 21:08:26 -07:00
124next-token.subx 6632 2020-07-11 00:11:39 -07:00
125write-stream-data.subx 6612 - reorganize layers 2020-07-05 12:13:28 -07:00
126write-int-decimal.subx 6627 2020-07-10 21:08:26 -07:00
127next-word.subx 6612 - reorganize layers 2020-07-05 12:13:28 -07:00
128subx-words.subx 6632 2020-07-11 00:11:39 -07:00
129emit-hex.subx 6612 - reorganize layers 2020-07-05 12:13:28 -07:00
130emit.subx 6612 - reorganize layers 2020-07-05 12:13:28 -07:00
131table.subx 6627 2020-07-10 21:08:26 -07:00
132slurp.subx 6612 - reorganize layers 2020-07-05 12:13:28 -07:00
133subx-widths.subx 6632 2020-07-11 00:11:39 -07:00
134emit-hex-array.subx 6612 - reorganize layers 2020-07-05 12:13:28 -07:00
135next-word-or-string.subx 6612 - reorganize layers 2020-07-05 12:13:28 -07:00
200.txt 6612 - reorganize layers 2020-07-05 12:13:28 -07:00
201register-names.subx 6612 - reorganize layers 2020-07-05 12:13:28 -07:00
202write-int.subx 6612 - reorganize layers 2020-07-05 12:13:28 -07:00
203stack.subx 6612 - reorganize layers 2020-07-05 12:13:28 -07:00
300.txt 6643 2020-07-13 21:52:26 -07:00
301array-equal.subx 6627 2020-07-10 21:08:26 -07:00
302stack_allocate.subx 6612 - reorganize layers 2020-07-05 12:13:28 -07:00
303kernel-string.subx 6612 - reorganize layers 2020-07-05 12:13:28 -07:00
304screen.subx 6680 2020-07-26 22:08:22 -07:00
305keyboard.subx 6627 2020-07-10 21:08:26 -07:00
306files.subx 6612 - reorganize layers 2020-07-05 12:13:28 -07:00
307size.subx 6612 - reorganize layers 2020-07-05 12:13:28 -07:00
308allocate-array.subx 6682 - experimental support for streams and slices 2020-07-28 21:37:32 -07:00
309stream.subx 6687 - stream-empty? and stream-full? 2020-07-30 19:34:29 -07:00
400.mu 6687 - stream-empty? and stream-full? 2020-07-30 19:34:29 -07:00
401test.mu 6687 - stream-empty? and stream-full? 2020-07-30 19:34:29 -07:00
402time.mu 6686 2020-07-30 19:22:40 -07:00
403stream.mu 6687 - stream-empty? and stream-full? 2020-07-30 19:34:29 -07:00
README.md 6640 2020-07-12 16:37:58 -07:00
bootstrap 5865 2020-01-02 02:01:41 -08:00
bootstrap.md 6618 - new docs 2020-07-06 01:05:10 -07:00
build 6207 - tweaks while creating a video 2020-04-19 09:32:46 -07:00
build_and_test_until 5865 2020-01-02 02:01:41 -08:00
cheatsheet.pdf 5485 - promote SubX to top-level 2019-07-27 17:47:59 -07:00
clean 5865 2020-01-02 02:01:41 -08:00
edit 6416 2020-05-28 10:07:59 -07:00
editor.md 6618 - new docs 2020-07-06 01:05:10 -07:00
exuberant_ctags_rc 6081 - ctags for .mu files 2020-03-05 18:29:00 -08:00
index.html 5485 - promote SubX to top-level 2019-07-27 17:47:59 -07:00
init.linux 6622 - new syscalls: time and ntime 2020-07-08 22:14:42 -07:00
init.soso 5886 2020-01-12 21:30:29 -08:00
modrm.pdf 5485 - promote SubX to top-level 2019-07-27 17:47:59 -07:00
mu-init-test.subx 6153 - switch 'main' to use Mu strings 2020-03-15 21:03:12 -07:00
mu-init.subx 6393 - start running .mu apps in CI 2020-05-24 20:36:31 -07:00
mu.dte 6175 - syntax highlighting for dte 2020-03-29 13:25:00 -07:00
mu.md 6657 2020-07-16 22:34:57 -07:00
mu.vim 6634 - highlight bad variables in vim 2020-07-11 21:20:06 -07:00
mu_instructions 6657 2020-07-16 22:34:57 -07:00
run_one_test 6200 - --dump is not needed for incremental traces 2020-04-09 00:56:32 -07:00
run_one_test.subx 6072 2020-02-29 22:36:03 -08:00
sib.pdf 5485 - promote SubX to top-level 2019-07-27 17:47:59 -07:00
stats.txt 6674 2020-07-25 15:35:43 -07:00
subx.dte 6176 2020-03-29 14:13:03 -07:00
subx.el 5843 2019-12-29 13:40:22 -08:00
subx.gedit 5841 - rudimentary syntax highlighting for gedit 2019-12-28 20:02:45 -08:00
subx.md 6640 2020-07-12 16:37:58 -07:00
subx.nanorc 5840 - syntax highlighting for nano (!!) 2019-12-28 19:16:24 -08:00
subx.vim 6398 2020-05-24 22:47:09 -07:00
subx_bare.md 6640 2020-07-12 16:37:58 -07:00
subx_debugging.md 6640 2020-07-12 16:37:58 -07:00
subx_opcodes 6126 - support 8-byte register names 2020-03-11 18:16:56 -07:00
test_apps 6618 - new docs 2020-07-06 01:05:10 -07:00
test_layers 6614 2020-07-05 12:43:00 -07:00
translate_mu 6611 - start adding to common vocabulary in Mu 2020-07-05 10:41:41 -07:00
translate_mu_debug 6611 - start adding to common vocabulary in Mu 2020-07-05 10:41:41 -07:00
translate_subx 6527 - increase stack limits 2020-06-15 16:16:00 -07:00
translate_subx_debug 6401 - have scripts follow the Unix way 2020-05-24 22:57:07 -07:00
translate_subx_emulated 6401 - have scripts follow the Unix way 2020-05-24 22:57:07 -07:00
vimrc.vim 6565 - support tmux in control mode 2020-06-21 14:08:30 -07:00
vocabulary.md 6658 2020-07-18 15:56:32 -07:00

README.md

Mu: a human-scale computer

Mu is a minimal-dependency hobbyist computing stack (everything above the processor and OS kernel).

Mu is not designed to operate in large clusters providing services for millions of people. Mu is designed for you, to run one computer. (Or a few.) Running the code you want to run, and nothing else.

$ git clone https://github.com/akkartik/mu
$ cd mu
$ ./translate_mu apps/ex2.mu  # emit a.elf
$ ./a.elf  # adds 3 and 4
$ echo $?
7

Build Status

Rather than start from some syntax and introduce layers of translation to implement it, Mu starts from the processor's instruction set and tries to get to some safe and clear syntax with as few layers of translation as possible. The emphasis is on internal consistency at any point in time rather than compatibility with the past. (More details.)

Currently Mu requires a 32-bit x86 processor and Linux kernel.

Goals

In priority order:

  • Reward curiosity.
  • Safe.
    • Thorough test coverage. If you break something you should immediately see an error message. If you can manually test for something you should be able to write an automated test for it.
    • Memory leaks over memory corruption.
  • Teach the computer bottom-up.

Non-goals

  • Speed. Staying close to machine code should naturally keep Mu fast enough.
  • Efficiency. Controlling the number of abstractions should naturally keep Mu using far less than the gigabytes of memory modern computers have.
  • Portability. Mu will run on any computer as long as it's x86. I will enthusiastically contribute to support for other processors -- in separate forks. Readers shouldn't have to think about processors they don't have.
  • Compatibility. The goal is to get off mainstream stacks, not to perpetuate them. Sometimes the right long-term solution is to bump the major version number.
  • Syntax. Mu code is meant to be comprehended by running, not just reading. For now it's a thin veneer over machine code. I'm working on memory safety before expressive syntax.

Toolchain

The Mu stack consists of:

  • the Mu type-safe language;
  • SubX, an unsafe notation for a subset of x86 machine code; and
  • bare SubX, a more rudimentary form of SubX without certain syntax sugar.

All Mu programs get translated through these layers into tiny zero-dependency ELF binaries. The translators for most levels are built out of lower levels. The translator from Mu to SubX is written in SubX, and the translator from SubX to bare SubX is built in bare SubX.

Mu programs can be run in emulated mode to emit traces, which permit time-travel debugging. (More details.)

incomplete tools

The Mu translator is still a work in progress; not all incorrect programs result in good error messages.

Once generated, ELF binaries can be packaged up with a Linux kernel into a bootable disk image:

$ ./translate_mu apps/ex2.mu  # emit a.elf
# dependencies
$ sudo apt install build-essential flex bison wget libelf-dev libssl-dev xorriso
$ tools/iso/linux a.elf
$ qemu-system-x86_64 -m 256M -cdrom mu_linux.iso -boot d

The disk image also runs on any cloud server that supports custom images.

Mu also runs on the minimal hobbyist OS Soso. (Requires graphics and sudo access. Currently doesn't work on a cloud server.)

$ ./translate_mu apps/ex2.mu  # emit a.elf
# dependencies
$ sudo apt install build-essential util-linux nasm xorriso  # maybe also dosfstools and mtools
$ tools/iso/soso a.elf  # requires sudo
$ qemu-system-i386 -cdrom mu_soso.iso

Syntax

The entire stack shares certain properties and conventions. Programs consist of functions and functions consist of statements, each performing a single operation. Operands to statements are always variables or constants. You can't say a + b*c, you have to break it up into two operations. Variables can live in memory or in registers. Registers must be explicitly specified. There are some shared lexical rules; comments always start with '#', and numbers are always written in hex.

Here's an example program in Mu:

ex2.mu

More details on Mu syntax →

Here's an example program in SubX:

== code
Entry:
  # ebx = 1
  bb/copy-to-ebx  1/imm32
  # increment ebx
  43/increment-ebx
  # exit(ebx)
  e8/call  syscall_exit/disp32

More details on SubX syntax →

Forks

Forks of Mu are encouraged. If you don't like something about this repo, feel free to make a fork. If you show it to me, I'll link to it here, so others can use it. I might even pull your changes into this repo!

  • mu-normie: with a more standard build system and C++ modules.

Desiderata

If you're still reading, here are some more things to check out:

Credits

Mu builds on many ideas that have come before, especially: