1. 前言
qemu支持自定義開發板,本文就記錄一下折騰的過程。基于qemu-10.0.0-rc3
添加x210vb3s
開發板。
2. 添加板卡文件
網上參考了一些文章,有些文章使用的版本和我的不一樣,折騰起來費了點時間,最后發現還是直接參考qemu中已有的開發板文件比較快捷,經過一些嘗試,最后選擇參考hw/arm/xilinx_zynq.c
來編寫我的開發板文件,并經過一番嘗試,移除了一些無關緊要的代碼,得到一個能運行的最簡版本。
- 新增
hw/arm/x210vb3s.c
#include "qemu/osdep.h"
#include "hw/boards.h"
#include "hw/arm/boot.h"
#include "hw/loader.h"
#include "qapi/error.h"struct BoardState {/*< private >*/MachineState parent;/*< public >*/ARMCPU *cpu[1];MemoryRegion iram;MemoryRegion dram;
};/* 此處定義的宏的名字是局部的,字符串“x210bv3s”需要全局唯一 */
#define TYPE_BOARD MACHINE_TYPE_NAME("x210bv3s")
OBJECT_DECLARE_SIMPLE_TYPE(BoardState, BOARD)static struct arm_boot_info boot_info = {/* 該值需要比-kernel指定的可執行文件要大,此處0x18000(96KB)是iRAM的大小,運行裸機程序時,-kernel后面應當指定elf文件 */.ram_size = 0x18000,
};static void board_init(MachineState *ms)
{BoardState *s = BOARD(ms);MachineClass *mc = MACHINE_GET_CLASS(ms);MemoryRegion *system_mem = get_system_memory();/* 創建CPU,如果不創建,qemu啟動后會提示無CPU */Object *cpuobj = object_new(mc->default_cpu_type);qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);s->cpu[0] = ARM_CPU(cpuobj);/* 創建iRAM,如果不添加內存,則qemu啟動后無法訪問任何內存,程序也不能正常加載和執行 *//* iRAM: 0xD0020000-0xD0038000:96KB */memory_region_init_ram(&s->iram, NULL, "iram",0xD0038000-0xD0020000, &error_fatal);memory_region_add_subregion(system_mem, 0xD0020000, &s->iram);/* 啟動-kernel的加載,不執行該函數qemu可以連接gdb,但是不會執行-kernel指定的文件 */arm_load_kernel(s->cpu[0], ms, &boot_info);
}static void board_class_init(ObjectClass *oc, void *data)
{MachineClass *mc = MACHINE_CLASS(oc);static const char * const valid_cpu_types[] = {ARM_CPU_TYPE_NAME("cortex-a8"),NULL};mc->desc = "X210BV3S S5PV210 (Cortex-A8)";mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a8");mc->valid_cpu_types = valid_cpu_types;mc->init = board_init;/* 定義該值為true,程序訪問非法內存時不會產生內存訪問異常 */mc->ignore_memory_transaction_failures = false;
}static const TypeInfo board_info = {.name = TYPE_BOARD,.parent = TYPE_MACHINE,.instance_size = sizeof(BoardState),.class_init = board_class_init,
};static void machine_register(void)
{type_register_static(&board_info);
}type_init(machine_register)
3. 修改編譯文件
hw/arm/Kconfig
,按照已有內容格式添加如下內容,可以添加到文件結尾處,default y
表示啟動編譯,否者不會參與編譯。
config X210BV3Sbooldefault y
hw/arm/meson.build
,按照已有內容添加如下內容,注意是arm_ss
不是system_ss
,這個問題也折騰了我好久,它們兩個都會被編譯,但是編譯的參數略有不同,此處的編譯條件CONFIG_X210BV3S
已經在hw/arm/Kconfig
中使能了,所以會被編譯。
arm_ss.add(when: 'CONFIG_X210BV3S', if_true: files('x210bv3s.c'))
4. 重新編譯
# 啟動容器,需要在容器中編譯,我之前的容器停止了,此處直接啟動即可
$ docker start -i qemu
# 此處進入容器環境
$ cd /qemu/build
# 重新配置工程,只編譯qemu-system-arm程序
$ ../configure --target-list=arm-softmmu
# 此時是追加編譯很快就結束了
$ make -j24
# 查看新增的開發板,已經存在了
$ ./qemu-system-arm -M help
x210bv3s X210BV3S S5PV210 (Cortex-A8)
5. 運行
參考qemu(1) – 安裝中的ctr0.S
,此處仍運行該程序。
# 因為沒有將arm-none-eabi工具鏈掛載到容器中,測試多有不便,所以我們可以在wsl中運行qemu-system-arm程序
$ cd qemu-10.0.0-rc3/build
# 啟動qemu,~/workspace/arm/x210bv3s/bare/start/crt0.elf是我之前創建crt0.S測試文件的位置
$ ./qemu-system-arm -M x210bv3s -kernel ~/workspace/arm/x210bv3s/bare/start/crt0.elf -S -s
# 新啟動一個窗口,運行arm-none-eabi-gdb,測試一切正常
上一篇:qemu(1) – 安裝
下一篇:qemu(2) – 定制開發板
目錄:全部文章合集
參考
如何使用 QEMU 模擬一塊開發板
基于qemu從0開始構建嵌入式linux系統