juice vm诞生于2020年,以实现可运行最新kernel主线的RISC-V最小虚拟机为目标而诞生的,设计之初秉承着可以在 RAM 只有 百KB 级别的平台上运行,不引入除了c99标准外的第三方依赖。
juice vm按照gcc所支持的C99标准编写,无第三方库依赖,浅显易懂,且具有方便移植的特性(可快速移植到多种主流 MCU 及支持c环境的所有平台上)。
juice vm去掉注释后展开所有的宏的代码行数仅12523行,仅36104字,足够的小巧。
虚拟机版本号 | 起始地址 | 大小(字节) | 寄存器名称 | 说明 | 所用宏名称 |
---|---|---|---|---|---|
430de41bc | 0x80000000 | 0x12C00000 | SRAM | 内部存储 | RV_CPU_SIM_RAM_START_ADDR RV_CPU_SIM_RAM_SIZE |
430de41bc | pdev_uart0_write_addr | 0x1 | UART_WRITE | uart发送寄存器 | pdev_uart0_write_addr |
430de41bc | pdev_uart0_read_addr | 0x1 | UART_READ | uart接收寄存器 | pdev_uart0_read_addr |
430de41bc | pdev_uart0_state_addr | 0x1 | UART_STATE | uart状态寄存器 | pdev_uart0_state_addr pdev_uart0_free_state pdev_uart0_readbusy_state |
430de41bc | rv_sim_pdev_clint_mtime_addr | 0x8 | mtime | mtime当前计数寄存器 | rv_sim_pdev_clint_mtime_addr |
430de41bc | rv_sim_pdev_clint_mtimecmp_addr | 0x8 | mtimecmp | mtime当前比较寄存器 | rv_sim_pdev_clint_mtimecmp_addr |
430de41bc(linux only) | pdev_netcard0_write_addr | 0x1 | netcard0_write | 网卡发送缓冲区起始地址 | pdev_netcard0_write_addr |
430de41bc(linux only) | pdev_netcard0_write_end_addr | 0x1 | netcard0_write_end | 网卡缓冲区末尾地址 | pdev_netcard0_write_end_addr |
430de41bc(linux only) | pdev_netcard0_write_cnt_H_addr | 0x1 | netcard0_write_cnt_H | 网卡发送缓冲区数据大小高8位 | pdev_netcard0_write_cnt_H_addr |
430de41bc(linux only) | pdev_netcard0_write_cnt_L_addr | 0x1 | netcard0_write_cnt_L | 网卡发送缓冲区数据大小低8位 | pdev_netcard0_write_cnt_L_addr |
430de41bc(linux only) | pdev_netcard0_write_start_addr | 0x1 | netcard0_write_start | 网卡使能发送 | pdev_netcard0_write_start_addr |
430de41bc(linux only) | pdev_netcard0_read_addr | 0x1 | netcard0_read | 网卡接收缓冲区起始地址 | pdev_netcard0_read_addr |
430de41bc(linux only) | pdev_netcard0_read_end_addr | 0x1 | netcard0_read_end | 网卡接收缓冲区末尾地址 | pdev_netcard0_read_end_addr |
430de41bc(linux only) | pdev_netcard0_readbuf_cnt_H_addr | 0x1 | netcard0_readbuf_cnt_H | 网卡接收缓冲区数据大小高8位 | pdev_netcard0_readbuf_cnt_H_addr |
430de41bc(linux only) | pdev_netcard0_readbuf_cnt_L_addr | 0x1 | netcard0_readbuf_cnt_L | 网卡接收缓冲区数据大小低8位 | pdev_netcard0_readbuf_cnt_L_addr |
430de41bc(linux only) | pdev_netcard0_state_addr | 0x1 | netcard0_state | 网卡当前状态 | pdev_netcard0_state_addr pdev_netcard0_free_state pdev_netcard0_readbusy_state |
430de41bc | pdev_fb0_write_x_H_addr | 0x1 | fb0_write_x_H | fb0写坐标x高8位 | pdev_fb0_write_x_H_addr |
430de41bc | pdev_fb0_write_x_L_addr | 0x1 | fb0_write_x_L | fb0写坐标x低8位 | pdev_fb0_write_x_L_addr |
430de41bc | pdev_fb0_write_y_H_addr | 0x1 | fb0_write_y_H | fb0写坐标y高8位 | pdev_fb0_write_y_H_addr |
430de41bc | pdev_fb0_write_y_L_addr | 0x1 | fb0_write_y_L | fb0写坐标y低8位 | pdev_fb0_write_y_L_addr |
430de41bc | pdev_fb0_write_r_addr | 0x1 | fb0_write_r_ | fb0写坐标红色分量 | pdev_fb0_write_r_addr |
430de41bc | pdev_fb0_write_g_addr | 0x1 | fb0_write_g | fb0写坐标绿色分量 | pdev_fb0_write_g_addr |
430de41bc | pdev_fb0_write_b_addr | 0x1 | fb0_write_g | fb0写坐标蓝色分量 | pdev_fb0_write_b_addr |
430de41bc | pdev_fb0_write_set_addr | 0x1 | fb0_write_set | fb0设置颜色 | pdev_fb0_write_set_addr |
430de41bc | pdev_fb0_write_render_addr | 0x1 | fb0_write_render | fb0使能渲染 | pdev_fb0_write_render_addr |
- UBUNTU/DEBIAN APT安装
echo "deb http://xiaohui.mongoyun.com:3333/ trusty main" | sudo tee -a /etc/apt/sources.list
wget -O - http://xiaohui.mongoyun.com:3333/key/deb.gpg.key | sudo apt-key add -
sudo apt update
sudo apt install juicevm
juicevm
wget -O juice_vm_release_for_Linux_laster.zip https://github.com/juiceRv/JuiceVm/raw/master/juice_vm_release_for_Linux_laster.zip
unzip juice_vm_release_for_Linux_laster.zip
cd linux
sudo chmod +x juicevm_rv64_for_linux.out
./juicevm_rv64_for_linux.out
编译中
参数 | 参数名称 | 说明 |
---|---|---|
t | enable test mode | 进入固件测试模式当出现下面的状态会结束运行并且打印出通过还是失败的字样,x3_gp寄存器的值为1 和 x17_a7寄存器的值为93时,进入了ecall异常就会触发。x10_a0 寄存器的值为 0时打印pass字样,否则打印fail字样 |
T | enable trap debug mode | 使能异常调试模式,出现异常时会打印当前异常的调试信息 |
d | enable debug mode | 打开虚拟机内所有的调试选项,输出最详细的调试信息,包括指令译码,处理执行,当前寄存器列表,csr列表等 |
c | print cst operation msg | 打开虚拟机的csr寄存器读写调试信息。读写csr寄存器的时候都会打印对应的csr寄存器的值 |
a | diable all debug msg | 关闭所有调试选项,译码调试默认打开 |
x | enable test mode for exception | 打开异常测试模式,当出现异常时结束运行 |
g | enable better readability printing | 使用可读性更好的方式打印信息 |
e | disable all error msg | 关闭所有的错误信息打印 |
i | enable all instr debug msg | 打开所有指令调试信息打印 |
m | enable mmu debug msg | 打开mmu的遍历调试信息 |
p | print mmu page 8 byte data | hexdump打印mmu页表里的8字节数据 |
P | print mmu page 4K Byte data | hexdump打印mmu页表里的4K字节数据 |
s | uart addr not use mmu translation | 启用mmu翻译时,忽略uart的外设地址,在启用了mmu的时候也可以直接通过uart原始物理地址来操作uart外设 |
S | switch mode debug info | 打开切换mode时的调试信息,m-mode,s-mode和u-mode切换的时候都会打印调试信息 |
M | disable mmu err msg | 关闭mmu缺页异常,访问异常,加载异常的错误信息 |
r | enable trap debug msg | 打印更详细的进入中断的调试信息 |
A | enable addr translation debug print | 打印地址转换的调试打印 |
L (n) | log mode | output_mode_sel n = 0 -> stdout1 -> log_buf UNIX SYS ONLY(buf_size:(2900))2 -> none选择虚拟机输出的方式,1,直接标准输出。2,使用一个buf先缓存,退出的时候再输出bug大小2900Byte。3,不输出。 |
l | enable endless loop check (RV_ENDLESS_LOOP_CHECK_EXIT_CNT:(3)) | 启用死循环监测机制,当有连续3次出现同样的指令执行流程(包括寄存器和csr寄存器的值都没有改变),结束虚拟机的运行。可以搭配-L参数使用,方便调试固件。一般assert都是直接死循环。 |
挖坑网首发 感谢晕哥一路的支持
提交了RT-Thread 的适配 到官方仓库:详情请点击https://github.com/RT-Thread/rt-thread/tree/master/bsp/juicevm
1.已完成rt-thread移植。
无第三方库不到5000行C语言实现一个risc-v虚拟机,带mmu
基于指令集 rv64i
实现了mtime,超级精简的uart和mmu sv39.
更多回帖