m_genesis.kv 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
m_genesis.kv 2 ;; 'M', a MIPS system emulator. ;;
m_genesis.kv 3 ;; Version: 300K. ;;
m_genesis.kv 4 ;; ;;
m_genesis.kv 5 ;; Will run lightly-modified Linux kernels with full isolation vs. host. ;;
m_genesis.kv 6 ;; To keep things simple, dynamic recompilation a la Bellard's is NOT USED! ;;
m_genesis.kv 7 ;; ;;
m_genesis.kv 8 ;; 'M' aims to 'fit-in-head'. As such, a reasonably complete description ;;
m_genesis.kv 9 ;; of the emulated machine architecture is included in the comments. ;;
m_genesis.kv 10 ;; ;;
m_genesis.kv 11 ;; Dependencies/Libraries required : NONE!!! ;;
m_genesis.kv 12 ;; Where Runs: Any AMD64 linux. ;;
m_genesis.kv 13 ;; ;;
m_genesis.kv 14 ;; To build: ;;
m_genesis.kv 15 ;; 'make' (needs 'gnumake') ;;
m_genesis.kv 16 ;; or: ;;
m_genesis.kv 17 ;; (1) yasm -f elf64 -g null m.asm ;;
m_genesis.kv 18 ;; (2) ld m.o -o m ;;
m_genesis.kv 19 ;; (3) strip m ;;
m_genesis.kv 20 ;; At the time of writing, yields a <13kB ELF. ;;
m_genesis.kv 21 ;; ;;
m_genesis.kv 22 ;; To run: ;;
m_genesis.kv 23 ;; ./bin/m kernel.bin ;;
m_genesis.kv 24 ;; ;;
m_genesis.kv 25 ;; Note: currently the only means to exit (other than 'kill -9') is to ;;
m_genesis.kv 26 ;; shut down the guest OS (In 'busybox' -- 'poweroff' command.) ;;
m_genesis.kv 27 ;; ;;
m_genesis.kv 28 ;; Devices Currently Emulated (see 'devices' dir) : ;;
m_genesis.kv 29 ;; MIPS Timer, 100Hz Timer, UART Console, Realtime Clock, Power Switch. ;;
m_genesis.kv 30 ;; ;;
m_genesis.kv 31 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
m_genesis.kv 32 ;; ;;
m_genesis.kv 33 ;; (C) 2019 Stanislav Datskovskiy ( www.loper-os.org ) ;;
m_genesis.kv 34 ;; http://wot.deedbot.org/17215D118B7239507FAFED98B98228A001ABFFC7.html ;;
m_genesis.kv 35 ;; ;;
m_genesis.kv 36 ;; You do not have, nor can you ever acquire the right to use, copy or ;;
m_genesis.kv 37 ;; distribute this software ; Should you use this software for any purpose, ;;
m_genesis.kv 38 ;; or copy and distribute it to anyone or in any manner, you are breaking ;;
m_genesis.kv 39 ;; the laws of whatever soi-disant jurisdiction, and you promise to ;;
m_genesis.kv 40 ;; continue doing so for the indefinite future. In any case, please ;;
m_genesis.kv 41 ;; always : read and understand any software ; verify any PGP signatures ;;
m_genesis.kv 42 ;; that you use - for any purpose. ;;
m_genesis.kv 43 ;; ;;
m_genesis.kv 44 ;; See also http://trilema.com/2015/a-new-software-licensing-paradigm . ;;
m_genesis.kv 45 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
m_genesis.kv 46
m_genesis.kv 47 ;-----------------------------------------------------------------------------
m_genesis.kv 48 %include "knobs.asm" ; User-adjustable Knobs
m_genesis.kv 49 %include "log.asm" ; Eggogology and Warning reporting
m_genesis.kv 50 %include "os/linux.asm" ; Linux invariants and threading knob
m_genesis.kv 51 %include "os/linux_io.asm" ; Linux I/O routines
m_genesis.kv 52 %include "flags.asm" ; Emulator State Flags
m_genesis.kv 53 %include "mips.asm" ; MIPS CPU Invariants
m_genesis.kv 54 %include "i_decode.asm" ; MIPS Instruction Decoding
m_genesis.kv 55 %include "cpustate.asm" ; MIPS CPU State
m_genesis.kv 56 %include "mips_exc.asm" ; MIPS Exception Handler
m_genesis.kv 57 %include "irq.asm" ; MIPS Interrupts
m_genesis.kv 58 %include "ram.asm" ; Memory
m_genesis.kv 59 %include "bus.asm" ; Memory-Mapped Devices
m_genesis.kv 60 %include "mips_cpu.asm" ; MIPS CPU Cycle Execution
m_genesis.kv 61 %include "mipsinst/i_instrs.asm" ; I-Type MIPS Instructions
m_genesis.kv 62 %include "mipsinst/r_instrs.asm" ; R-Type MIPS Instructions
m_genesis.kv 63 %include "mipsinst/b_instrs.asm" ; B-Type MIPS Instructions
m_genesis.kv 64 %include "mipsinst/m_instrs.asm" ; M-Type MIPS Instructions
m_genesis.kv 65 %include "shutdown.asm" ; Termination Cleanup
m_genesis.kv 66 ;-----------------------------------------------------------------------------
m_genesis.kv 67
m_genesis.kv 68 ;-----------------------------------------------------------------------------
m_genesis.kv 69 ;; State
m_genesis.kv 70 ;-----------------------------------------------------------------------------
m_genesis.kv 71 section .bss
m_genesis.kv 72 arg0 resb 8 ; First Command Line Argument
m_genesis.kv 73 fd resb 8 ; FD of file containing kernel image
m_genesis.kv 74 ;-----------------------------------------------------------------------------
m_genesis.kv 75
m_genesis.kv 76 ;; TODO: 1) Make RAM size adjustable. 2) Eat kernels in ELF form ?
m_genesis.kv 77 ;; 3) Move ALL os-istic calls into os/linux.asm ?
m_genesis.kv 78 ;; 4) Right now we use 100% of host CPU. Need sleep in wait and futex.
m_genesis.kv 79 ;; 5) Need devices! particularly 'disk' and 'NIC'. (And FG...!)
m_genesis.kv 80 ;; 6) Bring UART0 console out as TCP-able?
m_genesis.kv 81 ;; 7) 'Suspend/Resume', out-of-band debuggisms?
m_genesis.kv 82 ;; 8) Tests!!! Particularly, per-instruction test cases! Can you write?
m_genesis.kv 83
m_genesis.kv 84 ;-----------------------------------------------------------------------------
m_genesis.kv 85 ; Start of Program.
m_genesis.kv 86 ;-----------------------------------------------------------------------------
m_genesis.kv 87 section .text
m_genesis.kv 88 global _start
m_genesis.kv 89 _start:
m_genesis.kv 90 ;; Get argc (# of command line arguments) :
m_genesis.kv 91 mov rax, [rsp]
m_genesis.kv 92 cmp rax, CMDLINE_ARG_COUNT + 1 ; The required arg. count
m_genesis.kv 93 je ._run
m_genesis.kv 94 ;; Not correct number of args? then print usage and exit:
m_genesis.kv 95 ._usage:
m_genesis.kv 96 EGGOG "Usage: ./M KERNEL"
m_genesis.kv 97 ._run:
m_genesis.kv 98 ;; Test if SSE2 instructions are available on this machine:
m_genesis.kv 99 mov eax, 1
m_genesis.kv 100 cpuid
m_genesis.kv 101 test edx, 0x4000000
m_genesis.kv 102 jnz ._xmm_ok
m_genesis.kv 103 EGGOG "Needs SSE2!"
m_genesis.kv 104 ._xmm_ok:
m_genesis.kv 105
m_genesis.kv 106 ;; Get 1st cmdline arg (path)
m_genesis.kv 107 mov rdi, [rsp + 16]
m_genesis.kv 108 mov [arg0], rdi
m_genesis.kv 109
m_genesis.kv 110 ;; fd = open(path, O_RDONLY)
m_genesis.kv 111 mov rax, SYS_OPEN
m_genesis.kv 112 mov rdi, [arg0] ; first arg
m_genesis.kv 113 mov rsi, 0 ; O_RDONLY
m_genesis.kv 114 syscall
m_genesis.kv 115 test rax, rax ; see if eggog
m_genesis.kv 116 jns ._ok ; if worked
m_genesis.kv 117 EGGOG "Could not read kernel from disk!"
m_genesis.kv 118 ._ok:
m_genesis.kv 119 mov [fd], rax ; else, save fd
m_genesis.kv 120
m_genesis.kv 121 ;; Mbytes = fstat(fd).st_size (footprint of initial image)
m_genesis.kv 122 mov rax, SYS_FSTAT
m_genesis.kv 123 sub rsp, statbuf.size ; make scratch
m_genesis.kv 124 mov rsi, rsp
m_genesis.kv 125 mov rdi, [fd]
m_genesis.kv 126 syscall
m_genesis.kv 127 mov rax, [rsp + statbuf.st_size]
m_genesis.kv 128 mov [Mbytes], rax
m_genesis.kv 129 add rsi, statbuf.size ; unmake scratch
m_genesis.kv 130
m_genesis.kv 131 ;; RAM size
m_genesis.kv 132 mov qword [RAMbytes], RAM_SIZE_MB * (1024 * 1024)
m_genesis.kv 133 call _ram_allocate
m_genesis.kv 134 mov [M], rax
m_genesis.kv 135
m_genesis.kv 136 ;; Load the given kernel into bottom of sim RAM:
m_genesis.kv 137 mov rax, SYS_READ
m_genesis.kv 138 mov rdi, [fd] ; fd of memory snapshot
m_genesis.kv 139 mov rsi, [M] ; where to put
m_genesis.kv 140 mov rdx, [Mbytes] ; read whole snapshot into bottom of sim ram
m_genesis.kv 141 syscall
m_genesis.kv 142
m_genesis.kv 143 ;; close(fd)
m_genesis.kv 144 mov rax, SYS_CLOSE
m_genesis.kv 145 mov rdi, [fd]
m_genesis.kv 146 syscall
m_genesis.kv 147
m_genesis.kv 148 ;; Initialize all MMIO Devices (and start all slave threads) :
m_genesis.kv 149 call _Phys_Devices_Initialize
m_genesis.kv 150
m_genesis.kv 151 ;-----------------------------------------------------------------------------
m_genesis.kv 152 _Master_Thread:
m_genesis.kv 153 call _ram_init ; Initialize RAM
m_genesis.kv 154 call _cpu_reset ; Reset the MIPS CPU
m_genesis.kv 155 jmp _cycle ; Start the engine
m_genesis.kv 156 ;-----------------------------------------------------------------------------