;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 'M', a MIPS system emulator. ;; ;; Version: 300K. ;; ;; ;; ;; Will run lightly-modified Linux kernels with full isolation vs. host. ;; ;; To keep things simple, dynamic recompilation a la Bellard's is NOT USED! ;; ;; ;; ;; 'M' aims to 'fit-in-head'. As such, a reasonably complete description ;; ;; of the emulated machine architecture is included in the comments. ;; ;; ;; ;; Dependencies/Libraries required : NONE!!! ;; ;; Where Runs: Any AMD64 linux. ;; ;; ;; ;; To build: ;; ;; 'make' (needs 'gnumake') ;; ;; or: ;; ;; (1) yasm -f elf64 -g null m.asm ;; ;; (2) ld m.o -o m ;; ;; (3) strip m ;; ;; At the time of writing, yields a <13kB ELF. ;; ;; ;; ;; To run: ;; ;; ./bin/m kernel.bin ;; ;; ;; ;; Note: currently the only means to exit (other than 'kill -9') is to ;; ;; shut down the guest OS (In 'busybox' -- 'poweroff' command.) ;; ;; ;; ;; Devices Currently Emulated (see 'devices' dir) : ;; ;; MIPS Timer, 100Hz Timer, UART Console, Realtime Clock, Power Switch. ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; (C) 2019 Stanislav Datskovskiy ( www.loper-os.org ) ;; ;; http://wot.deedbot.org/17215D118B7239507FAFED98B98228A001ABFFC7.html ;; ;; ;; ;; You do not have, nor can you ever acquire the right to use, copy or ;; ;; distribute this software ; Should you use this software for any purpose, ;; ;; or copy and distribute it to anyone or in any manner, you are breaking ;; ;; the laws of whatever soi-disant jurisdiction, and you promise to ;; ;; continue doing so for the indefinite future. In any case, please ;; ;; always : read and understand any software ; verify any PGP signatures ;; ;; that you use - for any purpose. ;; ;; ;; ;; See also http://trilema.com/2015/a-new-software-licensing-paradigm . ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;----------------------------------------------------------------------------- %include "knobs.asm" ; User-adjustable Knobs %include "log.asm" ; Eggogology and Warning reporting %include "os/linux.asm" ; Linux invariants and threading knob %include "os/linux_io.asm" ; Linux I/O routines %include "flags.asm" ; Emulator State Flags %include "mips.asm" ; MIPS CPU Invariants %include "i_decode.asm" ; MIPS Instruction Decoding %include "cpustate.asm" ; MIPS CPU State %include "mips_exc.asm" ; MIPS Exception Handler %include "irq.asm" ; MIPS Interrupts %include "ram.asm" ; Memory %include "bus.asm" ; Memory-Mapped Devices %include "mips_cpu.asm" ; MIPS CPU Cycle Execution %include "mipsinst/i_instrs.asm" ; I-Type MIPS Instructions %include "mipsinst/r_instrs.asm" ; R-Type MIPS Instructions %include "mipsinst/b_instrs.asm" ; B-Type MIPS Instructions %include "mipsinst/m_instrs.asm" ; M-Type MIPS Instructions %include "shutdown.asm" ; Termination Cleanup ;----------------------------------------------------------------------------- ;----------------------------------------------------------------------------- ;; State ;----------------------------------------------------------------------------- section .bss arg0 resb 8 ; First Command Line Argument fd resb 8 ; FD of file containing kernel image ;----------------------------------------------------------------------------- ;; TODO: 1) Make RAM size adjustable. 2) Eat kernels in ELF form ? ;; 3) Move ALL os-istic calls into os/linux.asm ? ;; 4) Right now we use 100% of host CPU. Need sleep in wait and futex. ;; 5) Need devices! particularly 'disk' and 'NIC'. (And FG...!) ;; 6) Bring UART0 console out as TCP-able? ;; 7) 'Suspend/Resume', out-of-band debuggisms? ;; 8) Tests!!! Particularly, per-instruction test cases! Can you write? ;----------------------------------------------------------------------------- ; Start of Program. ;----------------------------------------------------------------------------- section .text global _start _start: ;; Get argc (# of command line arguments) : mov rax, [rsp] cmp rax, CMDLINE_ARG_COUNT + 1 ; The required arg. count je ._run ;; Not correct number of args? then print usage and exit: ._usage: EGGOG "Usage: ./M KERNEL" ._run: ;; Test if SSE2 instructions are available on this machine: mov eax, 1 cpuid test edx, 0x4000000 jnz ._xmm_ok EGGOG "Needs SSE2!" ._xmm_ok: ;; Get 1st cmdline arg (path) mov rdi, [rsp + 16] mov [arg0], rdi ;; fd = open(path, O_RDONLY) mov rax, SYS_OPEN mov rdi, [arg0] ; first arg mov rsi, 0 ; O_RDONLY syscall test rax, rax ; see if eggog jns ._ok ; if worked EGGOG "Could not read kernel from disk!" ._ok: mov [fd], rax ; else, save fd ;; Mbytes = fstat(fd).st_size (footprint of initial image) mov rax, SYS_FSTAT sub rsp, statbuf.size ; make scratch mov rsi, rsp mov rdi, [fd] syscall mov rax, [rsp + statbuf.st_size] mov [Mbytes], rax add rsi, statbuf.size ; unmake scratch ;; RAM size mov qword [RAMbytes], RAM_SIZE_MB * (1024 * 1024) call _ram_allocate mov [M], rax ;; Load the given kernel into bottom of sim RAM: mov rax, SYS_READ mov rdi, [fd] ; fd of memory snapshot mov rsi, [M] ; where to put mov rdx, [Mbytes] ; read whole snapshot into bottom of sim ram syscall ;; close(fd) mov rax, SYS_CLOSE mov rdi, [fd] syscall ;; Initialize all MMIO Devices (and start all slave threads) : call _Phys_Devices_Initialize ;----------------------------------------------------------------------------- _Master_Thread: call _ram_init ; Initialize RAM call _cpu_reset ; Reset the MIPS CPU jmp _cycle ; Start the engine ;-----------------------------------------------------------------------------