# Minimal RISC-V core to boot Linux > 吳哲郁 ## Starting point The codebase is derinved from [microxblue/rv32_linux](https://github.com/microxblue/rv32_linux). ## Environment Setup ### RISC-V GNU Toolchain You could setup RISCV GNU toolchain by following the instruction in the [GitHub repository](https://github.com/riscv-collab/riscv-gnu-toolchain) or as the following. 1. Get the sources ``` $ git clone https://github.com/riscv/riscv-gnu-toolchain ``` 2. Change to the cloned directory ``` $ cd riscv-bnu-toolchain ``` 3. Configure the installed path, `march` and `mabi` ``` $ ./configure --prefix=/opt/riscv --with-arch=rv32ima_zicsr --with-abi=ilp32 ``` 4. Install the toolchain ``` $ make ``` 5. Add toolchain path to PATH ``` $ echo `export PATH="/opt/riscv/bin:$PATH"` >> ~/.bashrc $ source ~/.bashrc ``` ### [Verilator](https://github.com/verilator/verilator) > Verilator is a software programming tool which converts the hardware description language Verilog to a cycle-accurate behavioral model in the programming languages C++ or SystemC. Verilator is an open source projects. With it, we can run RTL simulation for this project without needing to use a paid EDA tool. To install Verilator, please follow the instructions on [the official website](https://verilator.org/guide/latest/install.html). ## Run Emulation To boot linux on the emulator, please run the following commands: 1. Change to to project directory ``` $ cd rv32_linux ``` 2. Run emulation ``` $ make emurun ``` If the emulation is successfully run, you will see the following boot log on the terminal ``` [ 0.000000] Linux version 6.10.0mini-rv32ima-00001-g9568811284f3-dirty (test@ubuntu) (riscv32-buildroot-linux-uclibc-gcc.br_real (Buildroot -g851edd24) 13.2.0, GNU ld (GNU Binutils) 2.40) #13 Sun Dec 15 11:06:43 PST 2024 [ 0.000000] Machine model: riscv-minimal-nommu,qemu [ 0.000000] earlycon: uart8250 at MMIO32 0xffff0400 (options '1000000') [ 0.000000] printk: legacy bootconsole [uart8250] enabled [ 0.000000] Zone ranges: [ 0.000000] Normal [mem 0x0000000080000000-0x0000000080fbffff] [ 0.000000] Movable zone start for each node [ 0.000000] Early memory node ranges [ 0.000000] node 0: [mem 0x0000000080000000-0x0000000080fbffff] [ 0.000000] Initmem setup node 0 [mem 0x0000000080000000-0x0000000080fbffff] [ 0.000000] riscv: base ISA extensions [ 0.000000] riscv: ELF capabilities [ 0.000000] Kernel command line: earlycon=uart8250,mmio32,0xffff0400,1000000 console=ttyS0 [ 0.000000] Dentry cache hash table entries: 2048 (order: 1, 8192 bytes, linear) [ 0.000000] Inode-cache hash table entries: 1024 (order: 0, 4096 bytes, linear) [ 0.000000] Built 1 zonelists, mobility grouping off. Total pages: 4032 [ 0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off [ 0.000000] Memory: 13440K/16128K available (1312K kernel code, 276K rwdata, 143K rodata, 673K init, 92K bss, 2688K reserved, 0K cma-reserved) [ 0.000000] SLUB: HWalign=64, Order=0-1, MinObjects=0, CPUs=1, Nodes=1 [ 0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0 [ 0.000000] riscv-intc: 32 local interrupts mapped [ 0.000000] clint: clint@11000000: timer running at 1000000 Hz [ 0.000000] clocksource: clint_clocksource: mask: 0xffffffffffffffff max_cycles: 0x1d854df40, max_idle_ns: 3526361616960 ns [ 0.000009] sched_clock: 64 bits at 1000kHz, resolution 1000ns, wraps every 2199023255500ns [ 0.002063] Console: colour dummy device 80x25 [ 0.002589] Calibrating delay loop (skipped), value calculated using timer frequency.. 2.00 BogoMIPS (lpj=10000) [ 0.003268] pid_max: default: 32768 minimum: 301 [ 0.004069] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear) [ 0.004621] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear) [ 0.016078] devtmpfs: initialized [ 0.024529] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns [ 0.025213] futex hash table entries: 256 (order: -1, 3072 bytes, linear) [ 0.038745] clocksource: Switched to clocksource clint_clocksource [ 0.109065] workingset: timestamp_bits=30 max_order=12 bucket_order=0 [ 0.336988] Serial: 8250/16550 driver, 1 ports, IRQ sharing disabled [ 0.350913] of_serial ffff0400.uart: error -ENXIO: IRQ index 0 not found [ 0.352841] printk: legacy console [ttyS0] disabled [ 0.355949] ffff0400.uart: ttyS0 at MMIO 0xffff0400 (irq = 0, base_baud = 62500) is a 16550 [ 0.356768] printk: legacy console [ttyS0] enabled [ 0.356768] printk: legacy console [ttyS0] enabled [ 0.357477] printk: legacy bootconsole [uart8250] disabled [ 0.357477] printk: legacy bootconsole [uart8250] disabled [ 0.387672] clk: Disabling unused clocks [ 0.394137] Freeing unused kernel image (initmem) memory: 668K [ 0.394639] This architecture does not have kernel memory protection. [ 0.395180] Run /init as init process Welcome to mini-rv32ima Linux Jan 1 00:00:00 login[21]: root login on 'console' ~ # ``` ## Run RTL Simulation To boot linux on the RTL simulation, please run the following commands: 1. Change to the project directory ``` $ cd rv32_linux ``` 2. Build simulation firmware ``` $ make simfw ``` 3. Change to simulation directory ``` $ cd Rv32Sim ``` 4. Run the Verilator compilation process ``` $ make bld ``` 5. Change to the project directory and run the simulation ``` $ cd .. $ make simrun ``` ## Reference - [Verilator](https://en.wikipedia.org/wiki/Verilator)