All Projects → akkartik → Mu

akkartik / Mu

Licence: gpl-2.0
Soul of a tiny new machine. More thorough tests → More comprehensible and rewrite-friendly software → More resilient society.

Programming Languages

assembly
5116 projects

Labels

Projects that are alternatives of or similar to Mu

Invaders
Invaders game in 512 bytes (boot sector)
Stars: ✭ 461 (-44.72%)
Mutual labels:  x86
Ffmpeg Android
FFMpeg/FFprobe compiled for Android
Stars: ✭ 592 (-29.02%)
Mutual labels:  x86
R2s R4s X86 Openwrt
OpenWrt for Nanopi R2S/R4S/X86
Stars: ✭ 783 (-6.12%)
Mutual labels:  x86
Steed
[INACTIVE] Rust's standard library, free of C dependencies, for Linux systems
Stars: ✭ 520 (-37.65%)
Mutual labels:  x86
The holy book of x86
A simple guide to x86 architecture, assembly, memory management, paging, segmentation, SMM, BIOS....
Stars: ✭ 577 (-30.82%)
Mutual labels:  x86
Squalr
Squalr Memory Editor - Game Hacking Tool Written in C#
Stars: ✭ 645 (-22.66%)
Mutual labels:  x86
Unicorn
Unicorn CPU emulator framework (ARM, AArch64, M68K, Mips, Sparc, PowerPC, RiscV, X86)
Stars: ✭ 4,934 (+491.61%)
Mutual labels:  x86
Beelzebub
The Lord of Flies - A hobby operating system
Stars: ✭ 24 (-97.12%)
Mutual labels:  x86
Rop Tool
A tool to help you write binary exploits
Stars: ✭ 590 (-29.26%)
Mutual labels:  x86
X86 Assembly Cheat
MOVED TO: https://github.com/cirosantilli/linux-kernel-module-cheat#userland-assembly SEE README. x86 IA-32 and x86-64 userland minimal examples tutorial. Hundreds of runnable asserts. Nice GDB setup. IO done with libc, so OS portable in theory. NASM and GAS covered. Tested in Ubuntu 18.04. Containers (ELF), linking, calling conventions. System land cheat at: https://github.com/cirosantilli/x86-bare-metal-examples, ARM cheat at: https://github.com/cirosantilli/arm-assembly-cheat
Stars: ✭ 773 (-7.31%)
Mutual labels:  x86
Renode
Renode - Antmicro's virtual development framework for complex embedded systems
Stars: ✭ 525 (-37.05%)
Mutual labels:  x86
Bddisasm
bddisasm is a fast, lightweight, x86/x64 instruction decoder. The project also features a fast, basic, x86/x64 instruction emulator, designed specifically to detect shellcode-like behavior.
Stars: ✭ 540 (-35.25%)
Mutual labels:  x86
Inc
an incremental approach to compiler construction
Stars: ✭ 702 (-15.83%)
Mutual labels:  x86
Subhook
Simple hooking library for C/C++ (x86 only, 32/64-bit, no dependencies)
Stars: ✭ 470 (-43.65%)
Mutual labels:  x86
Rappel
A linux-based assembly REPL for x86, amd64, armv7, and armv8
Stars: ✭ 818 (-1.92%)
Mutual labels:  x86
Flingos
An educational operating system written in C#. A great stepping stone from high to low level development.
Stars: ✭ 451 (-45.92%)
Mutual labels:  x86
Remill
Library for lifting of x86, amd64, and aarch64 machine code to LLVM bitcode
Stars: ✭ 633 (-24.1%)
Mutual labels:  x86
Keypatch
Multi-architecture assembler for IDA Pro. Powered by Keystone Engine.
Stars: ✭ 939 (+12.59%)
Mutual labels:  x86
Distorm
Powerful Disassembler Library For x86/AMD64
Stars: ✭ 829 (-0.6%)
Mutual labels:  x86
Arm now
arm_now is a qemu powered tool that allows instant setup of virtual machines on arm cpu, mips, powerpc, nios2, x86 and more, for reverse, exploit, fuzzing and programming purpose.
Stars: ✭ 719 (-13.79%)
Mutual labels:  x86

Mu: a human-scale computer

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

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.

Here's the Mu computer running Conway's Game of Life.

$ git clone https://github.com/akkartik/mu
$ cd mu
$ ./translate life.mu  # emit a bootable disk.img
$ qemu-system-i386 disk.img
screenshot of Game of Life running on the Mu computer

(Colorized sources. This is memory-safe code, and most statements map to a single instruction of machine code.)

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.)

Tests are a key mechanism here for creating a computer that others can make their own. I want to encourage a style of active and interactive reading with Mu. If something doesn't make sense, try changing it and see what tests break. Any breaking change should cause a failure in some well-named test somewhere.

Currently Mu requires a 32-bit x86 processor.

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.

Thorough test coverage in particular deserves some elaboration. It implies that any manual test should be easy to turn into a reproducible automated test. Mu has some unconventional methods for providing this guarantee. It exposes testable interfaces for hardware using dependency injection so that tests can run on -- and make assertions against -- fake hardware. It also performs automated white-box testing which enables robust tests for performance, concurrency, fault-tolerance, etc.

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 memory-safe veneer over machine code. I'm working on a high-level "shell" for the Mu computer.

Toolchain

The Mu stack consists of:

  • the Mu type-safe and memory-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 binaries that run natively. 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. There is also an emulator for Mu's supported subset of x86, that's useful for debugging SubX programs.

Mu programs build natively either on Linux or on Windows using WSL 2. For Macs and other Unix-like systems, use the (much slower) emulator:

$ ./translate_emulated ex2.mu  # ~2 mins to emit disk.img

Mu programs can be written for two very different environments:

  • At the top-level, Mu programs emit a bootable image that runs without an OS (under emulation; I haven't tested on native hardware yet). There's just a screen and a keyboard, and that's it. No mouse, no hardware acceleration, no virtual memory, no process separation, no multi-tasking, no persistent storage, no network. All tests run on boot. main only runs if all tests pass.

  • The top-level is built using tools created under the linux/ sub-directory. This sub-directory contains an entirely separate set of standard libraries intended for building programs that run with just a Linux kernel, reading from stdin and writing to stdout. The Mu compiler is such a program, at linux/mu.subx. Individual programs typically run tests if given some commandline argument like test.

While I currently focus on programs without an OS, the linux/ sub-directory is fairly ergonomic. There's a couple of dozen example programs to try out there. It is likely to be the option for a network stack in the foreseeable future; I have no idea how to write to disk or interact on the network without Linux.

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 perform a + b*c in a single statement; you have to break it up into two. Variables can live in memory or in registers. Registers must be explicitly specified. There are some shared lexical rules. Comments always start with '#'. Numbers are always written in hex. Many terms can have context-dependent metadata attached after '/'.

Here's an example program in Mu:

ex2.mu

More resources on Mu:

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 resources on SubX:

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. I might even pull features upstream!

  • mu-normie: with a more standard build system that organizes the repo by header files and compilation units. Stays in sync with this repo.
  • mu-x86_64: experimental fork for 64-bit x86 in collaboration with Max Bernstein. It's brought up a few concrete open problems that I don't have good solutions for yet.
  • uCISC: a 16-bit processor being designed from scratch by Robert Butler and programmed with a SubX-like syntax.
  • subv: experimental SubX-like syntax by s-ol bekic for the RISC-V instruction set.

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:

  • Peter Naur for articulating the paramount problem of programming: communicating a codebase to others;
  • Christopher Alexander and Richard Gabriel for the intellectual tools for reasoning about the higher order design of a codebase;
  • David Parnas and others for highlighting the value of separating concerns and stepwise refinement;
  • The folklore of debugging by print and the trace facility in many Lisp systems;
  • Automated tests for showing the value of developing programs inside an elaborate harness;

On a more tactical level, this project has made progress in a series of bursts as I discovered the following resources. In autobiographical order, with no claims of completeness:

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].