Git Product home page Git Product logo

semu's Introduction

semu

A minimalist RISC-V system emulator capable of running Linux the kernel and corresponding userland. semu implements the following:

  • RISC-V instruction set architecture: RV32IMA
  • Privilege levels: S and U modes
  • Control and status registers (CSR)
  • Virtual memory system: RV32 MMU
  • UART: 8250/16550
  • PLIC (platform-level interrupt controller): 32 interrupts, no priority
  • Standard SBI, with the timer extension
  • VirtIO: virtio-blk acquires disk image from the host, and virtio-net is mapped as TAP interface

Prerequisites

Device Tree compiler (dtc) is required. To install it on Debian/Ubuntu Linux, enter the following command:

$ sudo apt install device-tree-compiler

For macOS, use the following command:

$ brew install dtc

For demonstration purposes, ext4 is used for file system mounting. ext4 is a native Linux filesystem, offering stability, high capacity, reliability, and performance while requiring minimal maintenance. The mkfs.ext4 command can create an ext4 file system from disk partitions. This command is a symbolic link of the mke2fs command, and its usage is the same as the mke2fs command.

For most GNU/Linux distributions, mkfs.ext4 command should be installed in advance. For macOS, use the following command:

$ brew install e2fsprogs

Build and Run

Build the emulator:

$ make

Download prebuilt Linux kernel image:

$ make check

Please be patient while semu is running.

Reference output:

Starting syslogd: OK
Starting klogd: OK
Running sysctl: OK
Starting network: OK

Welcome to Buildroot
buildroot login:

Enter root to access shell.

You can exit the emulator using: <Ctrl-a x>. (press Ctrl+A, leave it, afterwards press X)

Usage

./semu -k linux-image [-b dtb-file] [-i initrd-image] [-d disk-image]
  • linux-image is the path to the Linux kernel Image.
  • dtb-file is optional, as it specifies the user-specified device tree blob.
  • initrd-image is optional, as it specifies the user-specified initial RAM disk image.
  • disk-image is optional, as it specifies the path of a disk image in ext4 file system for the virtio-blk device.

Build Linux kernel image and root file system

An automated build script is provided to compile the RISC-V cross-compiler, Busybox, and Linux kernel from source. Please note that it only supports the Linux host environment.

$ make build-image

License

semu is released under the MIT License. Use of this source code is governed by a MIT-style license that can be found in the LICENSE file.

semu's People

Contributors

chiangkd avatar chinyikming avatar fourcolor avatar jiggerchuang avatar jserv avatar onnokort avatar shengwen-tw avatar visitorckw avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

semu's Issues

Support macOS native networking

akihikodaki's patch set includes support for vmnet which offers more flexibility than -netdev user, and allows higher network throughput. (see akihikodaki/qemu@72a35bb).

Take QEMU for example. To enable bridge mode, replace:

    -device virtio-net-pci,netdev=net \
    -netdev user,id=net,ipv6=off \

with

    -netdev vmnet-macos,id=n1,mode=bridged,ifname=en0 \
    -device virtio-net,netdev=n1 \

vmnet also offers "host" and "shared" networking model:

   -netdev vmnet-macos,id=str,mode=host|shared[,dhcp_start_address=addr,dhcp_end_address=addr,dhcp_subnet_mask=mask]

caveats:

  1. vmnet requires running qemu as root, for now.
  2. current vmnet API (Apple) doesn't support setting MAC address, so it will be randomized every time the VM is started.
    To work around 2), for now it's possible to set the MAC address within the VM.

As root, create a file /etc/udev/rules.d/75-mac-vmnet.rules with the following content:

ACTION=="add", SUBSYSTEM=="net", KERNEL=="enp0s3", RUN+="/usr/bin/ip link set dev %k address 00:11:22:33:44:55"
replace enp0s3 with the name of your interface and 00:11:22:33:44:55 with the desired MAC address.

Reboot or issue a ip link set dev enp0s3 address 00:11:22:33:44:55 to change your MAC address.

Reference: macos-vmnet

Route MMU through RAM access methods, caching?

Hi,

I just ported your great little emu to a very unlikely architecture and whilst doing so, I had to tweak the MMU code to go through the RAM access methods as well. I propose the code would be a lot more portable if MMU RAM access calls corresponding methods/functions as well, so that RAM access can really be anything. The current way of having a pointer into emu RAM is a bit of a breach of abstraction IMO.

I further noticed that every CPU instruction fetch goes through the MMU page walk and a very simple "1-entry-1-page" cache (one for INSN fetch, load & store) speeds up the emulation considerably. For the standard PC build, I got from about 10s to boot the emulated Linux to about 7s just by caching the current page for mmu_fetch.

As my code to do so is quite peculiar and adapted to the odd target architecture, I don't think it really fits well as an upstream patch. Still, I like to raise the issue of the MMU being direct-access here.

RFC: Integrate riscv-tests

Hello,
I would like to integrate riscv-tests into semu project.

Which is recommended way to implement test into semu?

  1. Assign only one test binary to semu. The test command would be

    ./semu riscv-tests ./test/riscv-tests/rv64ui_p_add
    

    The implementation is trivial, just read binary and allocate CPU one time like current semu does.
    But we need to type specific command for each test.

  2. Assign a test folder to semu. Semu has a loop to execute test binaries one by one in that folder.

    ./semu riscv-tests ./test/riscv-tests/
    

    In this case, we can create another C file to maintain all the test cases
    But we also need to consider allocating/freeing CPU resources per test case, right? Including bus, UART pthread...
    It would be more complicated.

    The pseudo code would be:

    for test in riscv-tests
        Open and read one test binary
        Allocate new CPU, which includes RAM, bus, UART pthread, etc
        Start CPU with limited loop round
        Check if register a0 equals zero and show test result
        Free CPU
    end
    

Implement VirtIO GPU device

Currently semu does not support graphics rendering.

I think VirtIO GPU with 2D mode might be a good starting point to go.
Later we can then emulate mouse and keyboard for more sophisticated features.

Implement the loading of initrd image

At present, initrd is missing, which means users have to boot Linux with initramfs enabled. This might not be convenient for someone who expects to specify a customized userland and/or benchmark suite at an early stage.

Expected output:

  1. specify initrd-start and initrd-end in device tree.
  2. Add an option -i to specify initrd image along with the functionality to load.

Reference:

Run semu inside web browser via WebAssembly translation

WebAssembly is capable to port rv32emu to browser. Then, I would like to test the WebAssembly translation of the semu codebase to see if kernels (like Linux or xv6) can be booted in a browser in order to facilitate the further integration of semu to rv32emu.

I would like to start with the smaller codebase and boot xv6 first. A few technical points are as follows:

  1. It is necessary to simulate a new shell that is operating in a web frontend (Xterm.js is a good solution), after which the command is forwarded to the kernel's running shell. Some of the scope issues with the variables generated by Emscripten are confusing to me, so that I have implemented a hardcoded ls command to confirm the kernel is booted successfully. The demo below shows Emscripten's capability to boot a kernel.
  2. The sh shell's dollar sign ($) of xv6 does not flush after exec, possibly some source kernel code needs to be changed.

Demo: xv6

You shall see output of ls command like below:

$ .              1 1 1024
..             1 1 1024
README         2 2 2059
cat            2 3 25016
echo           2 4 23800
forktest       2 5 13688
grep           2 6 28568
init           2 7 24896
kill           2 8 23752
ln             2 9 23704
ls             2 10 27320
mkdir          2 11 23856
rm             2 12 23840
sh             2 13 43824
stressfs       2 14 24864
usertests      2 15 159064
grind          2 16 39424
wc             2 17 26208
zombie         2 18 23224
console        3 19 0

Next, command bridging from web frontend shell(Xterm.js) to real shell will be solved, and then boot the Linux kernel.

Implement hart state management

During emulation, the semu_start() function initializes a single HART with a hartid of 0 and a start_addr value of (RAM_SIZE - 1024 * 1024). This means that there is only one HART present throughout the emulation process.

However, HSM (Hart Stete Management) is a mechanism used to manage the state of processor cores and is commonly applied in multi-core processor systems. It involves saving and restoring the HART's register state, program counter, and other contents when switching between different tasks or processes.

In a single-core processor system (only one HART), frequent HART state switching is not required.

Expectations:
Implement multi-core RISC-V processor system followed HSM State Machine
image

Validation:
check cat/proc/cpuinfo, currently as follows:

# cat /proc/cpuinfo
processor	: 0
hart		: 0
isa		: rv32ima
mmu		: sv32
mvendorid	: 0x12345678
marchid		: 0x80000001
mimpid		: 0x1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.