QEMU - 在BMC中虚拟一个 EEPROM(i2C) 设备

参考链接:参考链接: https://zhuanlan.zhihu.com/p/565253278

学习OpenBMc 绕不开 Qemu,QEMU 可以在系统下虚拟一个mechine ,将编译好的mechine 放到 qemu 中运行,在没有硬件支持的情况下,这种仿真环境非常有助于opembmc 的前期开发。

https://www.qemu.org/docs/master/system/arm/aspeed.html

这里是qemu 中关于Aspeed 平台 编译和运行的介绍,可以看到QEMU 支持直接从镜像启动,也可以加载内核和设备树文件启动/。

下面 虚拟i2c 设备 以 Booting the ast2700-evb machine 这个章节的介绍为例:
如果想要虚拟一个i2c 设备,就要修改qemu 中关于 ast2700的配置,就要源码编译后运行。

下载 QEMU

直接下载QEMU 的源码:wget https://download.qemu.org/qemu-9.2.2.tar.xz
解压后得到源码文件
运行ast2700 的话,需要将target 平台设置为arcch64,编译安装

./configure --target-list=aarch64-softmmu
make -j20 && make install

配置自己的Qemu machine

  • hw/arm/aspeed.c

    这个文件中保存了Aspeed 中所有相关mechine,在这里添加一个Machine 他继承了Aspeed 通用machine,后面我们在这个配置上继续进行OEM 的修改。
    aspeed_machine_ast2700_evb_class_init 这个函数中 定义了mechine 的详细信息

{
        .name          = MACHINE_TYPE_NAME("ast2700-oem"),
        .parent        = TYPE_ASPEED_MACHINE,
        .class_init    = aspeed_machine_ast2700_evb_class_init,
    }
  • aspeed_machine_ast2700_evb_class_init

    这个函数中 我们要自定义一个i2c 设备,需要关注这个函数指针:
    amc->i2c_init = ast2700_oem_i2c_init;
    我们仿照 2700evb 的 模式添加 一个自定义的i2c 初始化函数:

static void ast2700_oem_i2c_init(AspeedMachineState *bmc)
{
    AspeedSoCState *soc = bmc->soc;
    I2CSlave *cpld_mux;

    /* Create the generic DC-SCM hardware */
    qcom_dc_scm_bmc_i2c_init(bmc);

    /* Now create the Firework specific hardware */
    const uint8_t oem_bmc_fruid[] = {
        0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x0e, 0x00, 0x5c,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    };

    const size_t oem_bmc_fruid_len = sizeof(oem_bmc_fruid);
    /* I2C7 CPLD MUX */
    cpld_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 7), "pca9546", 0x72);
    // DeviceState *dev;
    i2c_slave_create_simple(pca954x_i2c_get_bus(cpld_mux, 0), "pca9548", 0x70); //CPLD0 SSD mux
    
    // i2c_slave_create_simple(pca954x_i2c_get_bus(cpld_mux, 3), "TYPE_INA226", 0x88); //CPLD3 Voltage sensor
    at24c_eeprom_init_rom(pca954x_i2c_get_bus(cpld_mux, 3), 0x54, 128 * KiB, oem_bmc_fruid, oem_bmc_fruid_len);

    /* LM75 is compatible with TMP105 driver */
    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 0), TYPE_TMP105, 0x4d);
    
    at24c_eeprom_init_rom(aspeed_i2c_get_bus(&soc->i2c, 8), 0x54, 64 * KiB, oem_bmc_fruid, oem_bmc_fruid_len);
    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 8), TYPE_PCA955X, 0x20);
}

上面代码我们在bus 7 上添加了一个pca9546 的i2c mux,在这个mux 的channel3 上添加了一eeprom,内容固定在 oem_bmc_fruid 中。
aspeed.c 中还有其他machine 添加了其他设备,例如 TYPE_TMP105 等。
到这里,Qemu 里面设备驱动的 虚拟和配置就完成了,我们重新编译 QEMU 的源码 然后安装。
使用这个命令查看 已经存在的 type:qemu-system-aarch64 -machine help
可以看到已经存在的ast2700-oem type

接下来配置openbmc 这边

  • dts 里面配置 设备相关的i2c :
&i2c7 {
    status = "okay";
	i2c-switch@72 {
		compatible = "nxp,pca9546";
		reg = <0x72>;
		#address-cells = <1>;
		#size-cells = <0>;
		i2c-mux-idle-disconnect;
		channel_7_0: i2c@0 {
			#address-cells = <1>;
			#size-cells = <0>;
			reg = <0>;
			i2c-switch@70 {
				compatible = "nxp,pca9548";
				reg = <0x70>;
				#address-cells = <1>;
				#size-cells = <0>;

				channel_7_0_0: i2c@0 {
					#address-cells = <1>;
					#size-cells = <0>;
					reg = <0>;
				};

				channel_7_0_1: i2c@1 {
					#address-cells = <1>;
					#size-cells = <0>;
					reg = <1>;
				};
			};
		};

		channel_7_3: i2c@3 {
			#address-cells = <1>;
			#size-cells = <0>;
			reg = <3>;
			eeprom@54 {
				compatible = "atmel,24c02";
				reg = <0x54>;
				pagesize = <16>;
			};
		};
	};
};

注意这里需要在kernel 的config 中使能 pca954x 的驱动。

  • 编译 obmc 镜像文件。

运行oem 的QEMU Machine

运行的命令我们参考 QEMU 文档描述中关于Aspeed 2700 的描述:

IMGDIR=ast2700-default
UBOOT_SIZE=$(stat --format=%s -L ${IMGDIR}/u-boot-nodtb.bin)

$ qemu-system-aarch64 -M ast2700-oem \
     -device loader,force-raw=on,addr=0x400000000,file=${IMGDIR}/u-boot-nodtb.bin \
     -device loader,force-raw=on,addr=$((0x400000000 + ${UBOOT_SIZE})),file=${IMGDIR}/u-boot.dtb \
     -device loader,force-raw=on,addr=0x430000000,file=${IMGDIR}/bl31.bin \
     -device loader,force-raw=on,addr=0x430080000,file=${IMGDIR}/optee/tee-raw.bin \
     -device loader,cpu-num=0,addr=0x430000000 \
     -device loader,cpu-num=1,addr=0x430000000 \
     -device loader,cpu-num=2,addr=0x430000000 \
     -device loader,cpu-num=3,addr=0x430000000 \
     -smp 4 \
     -drive file=${IMGDIR}/image-bmc,format=raw,if=mtd \
     -nographic

这里面 -M ast2700-oem 要换成我们自定义的 Machine type。

启动以后 扫描 i2c 设备:
bus7上的i2c 设备
可以看到这几个设备都被内核驱动正确加载了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值