1 Star 4 Fork 0

shinian / Biscuit-VM

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
readme.md 11.44 KB
一键复制 编辑 原始数据 按行查看 历史
shinian 提交于 2021-10-29 19:06 . 10.29 update

Biscuit-VM

关于这个小项目...

简易硬件接口的虚拟机,能极大降低OS开发难度.

设计思想

为了给OS提供尽可能强大的功能,虚拟机按模块化设计,OS通过控制虚拟机的模块来获得自己想要的功能.一个模块可以是一个指令集,一个中断记录器,一种内存映射功能,一种分页方法或是一种设备管理器.

目前状态

已验证RV32IM+Zicsr指令集和虚拟内存方案,并已支持时钟设备和Console设备等一些简单设备(具体参照dev.md).
已支持xv6部分功能,HTIF设备和Block设备完成后可支持xv6全部功能.

整体结构

项目分为两个部分,一个是核心core部分,另一个是模块module部分.core仅提供最基本的虚拟机功能和module接入点. module则提供尽可能强大的功能,将module加载至core即可获得相应的功能.

CORE

基本结构

/* 基于riscv32的抽象CPU */
struct rv32cpu {
    magic_t magic;
    word pc;
    enum cpu_mode mode;
    struct {
        bool enable; 
        bool hdsig; // handle 信号,置1将在下一个clock立即处理中断
        bool pending;
        word source;
        word cause;
        struct {
            uint64 head;
            uint64 tail;
            struct intrp_desc data[NR_RING_ITEM];
            struct plock plk;
        } intrp_ring; // 中断环,未决中断在此排队
    } intrp;
    uint64 mtime; // 机器时间
    uint64 mtimcmp; // 机器时间比较
    bool mtie; // 时钟中断使能
    struct {
    bool stopsig;
    bool running;
    //struct plock plk; // 一般情况下只会有CPU线程和另外一个线程同时访问,使用Peterson lock大概率是安全的(已弃用)
    } stat;
    struct environ* env;
    word regs[x_num];
    struct {
    modid_t exhdlr_modid[MAX_MOD_ITEM]; // module的id
    struct module * exhdlr_base[MAX_MOD_ITEM];  // 指向module本体的指针
    cpu_exhdlr exhdlr_func[MAX_MOD_ITEM]; // module挂载在此的处理函数
    void * exhdlr_ctx[MAX_MOD_ITEM]; // module的上下文

    modid_t csrrw_modid[MAX_MOD_ITEM];
    struct module * csrrw_base[MAX_MOD_ITEM];
    cpu_csrrw csrrw_func[MAX_MOD_ITEM];
    void * csrrw_ctx[MAX_MOD_ITEM];

    modid_t decoder_modid[MAX_MOD_ITEM];
    struct module * decoder_base[MAX_MOD_ITEM];
    cpu_decoder decoder_func[MAX_MOD_ITEM];
    void * decoder_ctx[MAX_MOD_ITEM];
    } mods;
    struct {
        pthread_t id;
        pthread_attr_t attr;
        pthread_mutex_t mlk;
    } thread_info;
    pthread_mutex_t ctrl_mlk;
};

/* 外设控制器 */
struct devctl {
    magic_t magic;
    struct environ* env;
    struct {
        uint64 head;
        uint64 tail;
        struct dev_csrrw_req data[NR_RING_ITEM];
        struct plock plk;
    } csrrw_ring; // csr异步写环,支持异步启动外设
    struct {
        uint64 head;
        uint64 tail;
        struct intrp_desc data[NR_RING_ITEM];
        pthread_mutex_t mlk;
    } intrp_ring; // csr中断环,挂在devctl上的设备中断会在此排队
    struct {
    bool stopsig;
    bool running;
    bool pausesig;
    bool paused;
    pthread_mutex_t blk; // pause用,阻塞线程
    pthread_mutex_t mlk; // 设置sig时用
    } stat;
    struct {
    modid_t csrrw_modid[MAX_MOD_ITEM];
    struct module * csrrw_base[MAX_MOD_ITEM];
    dev_csrrw csrrw_func[MAX_MOD_ITEM];
    void * csrrw_ctx[MAX_MOD_ITEM];
    } mods;
    struct {
        pthread_t id;
        pthread_attr_t attr;
        pthread_mutex_t mlk;
    } thread_info;
    pthread_mutex_t ctrl_mlk;
};

/* 内存 */
struct memory {
    magic_t magic;
    struct environ* env;
    int8 * data;
    memaddr_t size;
    struct {
    modid_t virtrw_modid[MAX_MOD_ITEM];
    struct module * virtrw_base[MAX_MOD_ITEM];
    mem_virtrw virtrw_func[MAX_MOD_ITEM];
    void * virtrw_ctx[MAX_MOD_ITEM];
    
    modid_t phyrw_modid[MAX_MOD_ITEM];
    struct module * phyrw_base[MAX_MOD_ITEM];
    mem_phyrw phyrw_func[MAX_MOD_ITEM];
    void * phyrw_ctx[MAX_MOD_ITEM];
    } mods;
};

struct environ {
    uint64 magic;
    enum {
        ENV_STOPPED = 0x0,
        ENV_RUNNING = 0x1,
        ENV_PAUSED = 0x2
    } stat;
    struct rv32cpu cpu;
    struct memory mem;
    struct devctl dctl;
    struct module* mods[MAX_MODS];
    count_t mod_n;
    pthread_mutex_t ctrl_mlk;
    pthread_mutex_t mod_ctrl_mlk;
};

可用功能 (待完善)

/* 主要是核心内部使用 */
status cpu_init (struct rv32cpu* cpu, struct environ* env); 
/* CPU控制接口,可用值: RESET, START, STOP */
status cpu_ctrl (struct rv32cpu * cpu, enum cpu_ctl_arg arg);
/* 发起同步异常,无视其他异常,下一时钟立即执行 (通常是CPU内部异常) */
status cpu_raise_excep_sync (struct rv32cpu * cpu, word cause);
/* 发起异步异常,等待轮询 (通常是DEVCTL发起的中断) */
status cpu_raise_excep_async (struct rv32cpu * cpu, word cause);
/* 添加模块中的CPU功能 */
status cpu_add_module (struct rv32cpu * cpu, struct module * mod);
/* 移除模块中的CPU功能 */
status cpu_remove_module(struct rv32cpu * cpu, modid_t modid);

status env_init (struct environ * env, uint32 memsz);
/* 环境控制接口,可用值: RESET, START, STOP, PAUSE, RESUME */
status env_ctrl (struct environ * env, enum env_ctl_arg arg);
/* 添加模块 */
status env_add_module (struct environ * env, struct module * mod);
/* 移除模块 */
status env_remove_module (struct environ * env, modid_t modid);
/* 模块控制接口,可用值: START, STOP, PAUSE, RESUME, CTRL(自定义接口) */
status env_mod_ctrl (struct environ * env, modid_t modid, enum mod_ctl_arg arg, uint64 exarg);
/* 同步读写控制寄存器,等待CPU控制寄存器读写函数和DEVCTL控制寄存器读写函数全部执行完毕 (通常用于启动外设) */
status env_csrrw_sync (struct environ * env, csraddr_t addr, word send, word * recv, enum rwmod rw);
/* 异步读写控制寄存器,只等待CPU控制寄存器读写函数执行完毕后(通常用于控制CPU的某些功能) */
status env_csrrw_async (struct environ* env, csraddr_t addr, word send, word * recv, enum rwmod rw, struct req_stat * async_stat);

status mem_init (struct memory * mem, uint32 size, struct environ * env);
status mem_add_module (struct memory * mem, struct module * mod);
status mem_remove_module (struct memory * mem, modid_t modid);
/* 以保护(分页)模式访存 */
status mem_rw_virt (struct environ* env, memaddr_t addr, word send, word * recv, enum rwmod rw);
/* 以物理方式访存 */
status mem_rw_phy (struct environ* env, memaddr_t addr, word send, word * recv, enum rwmod rw);

status devctl_init (struct devctl * dctl, struct environ * env);
/* 发起异步异常,通常是设备(模块)发起的. 相较CPU中异步异常处理速度会很慢.主要是为了协调CPU和外设之间的速度差距(大概...也许会有用吧) */
status devctl_raise_excep_async (struct devctl * dctl, word cause);
status devctl_add_module (struct devctl * dctl, struct module * mod);
status devctl_remove_module(struct devctl * dctl, modid_t modid);
/* 设备控制器控制函数, 可用值: START, STOP, PAUSE, RESUME*/
status devctl_ctrl(struct devctl * dctl, enum dev_ctl_arg arg);

status modlist_add (struct modlist * list, struct module * mod);
status modlist_init (struct modlist * list);

MODULE

基本结构

  • module_item : 模块项目描述
struct module_item {
    magic_t magic;
    modid_t modid; // 模块id
    enum module_item_type type; // 模块类型,描述挂载位置
    void * context; // 当前mod上下文(可以理解为C++的this指针)
    union {
        void * ptr;
        cpu_csrrw cpu_csrrw_func; // CPU控制寄存器访问函数,挂载至cpu.mods.csrrw_func
        cpu_exhdlr cpu_exhdlr_func; // CPU中断处理函数,挂载至cpu.mods.exhdlr_func
        cpu_decoder cpu_decoder_func; // CPU指令译码函数,挂载至cpu.mods.decoder_func
        dev_csrrw dev_csrrw_func; // 设备控制寄存器访问函数,挂载至 devctl.mods.csrrw_func
        mem_virtrw mem_virtrw_func; // 内存访问(保护)函数,挂载至 mem.mods.virtrw_func
        mem_phyrw mem_phyrw_func; // 内存访问(物理)函数,挂载至 mem.mods.phyrw_func
    } func;
};
struct module {
    magic_t magic;
    modid_t modid;
    #define MAX_MOD_NAME_SZ 256
    char name[MAX_MOD_NAME_SZ]; //模块名
    void * context;
    mod_fn init; // 初始化
    mod_fn start; // 启动
    mod_fn stop; // 终止
    mod_fn pause; // 暂停
    mod_fn resume; // 恢复
    mod_fn migratable; // 当前状态是否可迁移
    mod_exfn modctl; //mod 控制接口
    struct {
    count_t item_n;
    struct module_item item_list[MAX_MOD_ITEM];
    } items; //模块项目描述列表
};

可用功能 (待完善)

/* 封装好的功能,给模块使用 */
/* 发起同步异常,通常是CPU内部模块发起(例如译码模块) */
status raise_excep_sync (struct environ* env, word cause);
/* 发起异步异常,通常是外设发起(例如输入输入模块) */
status raise_excep_async (struct environ* env, word cause);
/* 物理访存 */
status memrw_phy (struct environ* env, memaddr_t addr, word send, word * recv, enum rwmod rw);
/* 保护(分页)访存 */
status memrw_virt (struct environ* env, memaddr_t addr, word send, word * recv, enum rwmod rw);
/* 只等待CPU控制寄存器读写函数执行完毕后返回(高效,通常只用于CPU内部控制寄存器读写) */
status csrrw_lazy (struct environ* env, csraddr_t addr, word send, word * recv, enum rwmod rw, struct req_stat * async_stat);
/* 等待CPU和DEVCTL控制寄存器读写函数执行完毕后返回(低效,通常用于外设控制寄存器读写) */
status csrrw_sync  (struct environ* env, csraddr_t addr, word send, word * recv, enum rwmod rw);
/* 封装模块时用,将模块功能添加至模块 */
status module_add_item (struct module * mod, enum module_item_type type, void * context, void * func);
/* 环境模块控制接口,可用值: START, STOP, PAUSE, RESUME, CTRL(自定义接口) */
status env_ctrl_mod (struct environ* env, modid_t modid, enum mod_ctl_arg arg, uint64 exarg);
/* 为环境添加模块 */
status env_add_mod (struct environ * env, struct module * mod);
/* 为环境移除模块 */
status env_remove_mod (struct environ * env, modid_t modid);

一些设想

运行时切换指令集

描述:一种运行时切换指令集设想.假设CPU支持同时支持RV32G和MIPS指令集,RV32G可运行在M,S和U态,MIPS只可运行在U态,那么虚拟机中的OS就能同时运行RV32G系统程序和MIPS用户态程序.这在现实世界是很难做到的.

内存内计算

描述:另一种很新奇的想法就是启用内存内计算,因为系统的访存方法全部都由模块提供,且访存方法是可编程的,这就为内存内计算提供了可能.

热迁移

描述:OS能直接控制虚拟机的模块,因此OS可以完成更强大的功能.其中最典型的就是OS自身可以和其他Biscuit-VM通信.无需外界介入即可实现热迁移.

OS按需生成设备

描述:虚拟设备是可编程模块,模块可以动态生成和加载,因此OS可以根据自己需要告知Biscuit-VM生成对应的设备.

使用HTIF

描述:在没有实现OS全部功能时,使用Host-Target interface(HTIF)可以使虚拟机中用户态程序直接使用宿主机提供的系统调用.

使用MagicFS

描述:OS没有实现文件系统时,可使用虚拟机提供的MagicFS设备.MagicFS设备提供了十分强大的文件接口,能极大简化OS开发.

环境信息记录/重放

描述:Biscuit-VM提供了比较全面的接口,因此可以对虚拟机状态进行记录,同时也可以将这些记录重放.

马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C
1
https://gitee.com/shinian9712/biscuit.git
git@gitee.com:shinian9712/biscuit.git
shinian9712
biscuit
Biscuit-VM
master

搜索帮助

344bd9b3 5694891 D2dac590 5694891