上篇文章介绍了通过yocto编译rpi os的流程,并没有对其进行定制化修改。这篇介绍下在不修改原有项目菜单的情况下,扩展镜像特性定制OS,本篇的OS有以下特性:U盘从启动;开启UART;开启ssh添加 profile工具包添加wifi默认账号密码以及固定IP 环境:ubuntu 22.04raspiberry 4BU盘 64Gyocto 4.1.2vmware 16.2.4概念介绍 简单介绍下yocto项目组织中几个常用的概念,在本篇也有使用:layer:层,组织文件和目录结构的元数据(软件菜谱、配置文件)集合;recipe:菜谱,构建软件包的元数据,通过指令、描述符可以获取源代码、补丁、构建二进制等;metadata:元数据,包含recipe、conf、class等;class:类,提供逻辑封装和基本继承机制,模板通常定义成class供其他菜谱使用;append:追加文件,用于扩展现有的菜谱,追加文件的变量可以覆盖原有菜谱的变量。定制镜像layer yocto包含的几个默认层,可以通过bblayer.conf文件查看到,可以直接修改原有的meta数据进行定制化,这样会破坏元数据,并且在定制化多个OS时都会受到影响,新建layer达到解耦的目的: 默认层 通过新建layer作为定制OS的工作目录,通过yocto自带的devtool工具创建layer会自动将该layer追加到bblayer.conf中,也可以通过bitbake创建。cd ~xxx/poky source oe-init-build-env rpi-build cd .. devtool create-workspace meta-mylayer #在poky根目录下创建meta-mylayer meta-mylayer文件夹默认会生成conf文件夹,用于配置包含了哪些recipe。当通过devtool来扩展和新增recipe时,会自动在该目录下生成appends和recipe文件夹来保存recipe。U盘启动 上篇介绍了烧录镜像后可以通过修改cmdline.txt参数root=/dev/sda2来从U盘启动,每次烧录都要修改比较麻烦,这里通过扩展recipe修改默认启动盘: 查看meta-raspberrypi中bootfiles包含了哪些recipe,路径:meta-raspberrypi/recipes-bsp/bootfiles:rpi-bootfiles.bb rpi-cmdline.bb # 对应于/etc/cmdline.txt rpi-config_git.bb #对应于/etc/config.txt 查看rpi-cmdline.bb: 使用devtool工具扩展rpi-cmdline,会自动在路径meta-mylayer/appends中生成rpi-cmdline.bbappend,然后修改CMDLINE_ROOTFS参数:devtool modify -x rpi-cmdline在rpi-cmdline.bbappend中新增如下代码:CMDLINE_ROOTFS = "root=/dev/sda2 ${CMDLINE_ROOT_FSTYPE} rootwait"重新编译rpi-cmdline:bitbake rpi-cmdline -c cleansstate bitbake rpi-cmdline定制wifi开机自启以及静态IP 之前实验中每次刷镜像都要设置wifi名称和密码,而调试环境中的wifi一般不会变化,为了后续效率更搞,这里需要写入默认的wifi配置,并设置开机后自启,需要修改2个recipe:wpa-supplicant和init-ifupdown:wpa-supplicant:用于配置wifi用户名和密码。devtool modify -x wpa-supplicant 修改wpa_supplicant.conf,对应的配置文件路径为:vim meta-mylayer/sources/wpa-supplicant/oe-local-files/wpa_supplicant.conf-sane。 注:这里修改的是wpa_supplicant.conf-sane,而非wpa_supplicant.conf。在wpa-supplicant.bb中可以看到如下命令,即安装的时候会把wpa_supplicant.conf-sane修改成wpa_supplicant.conf: ctrl_interface=/var/run/wpa_supplicant ctrl_interface_group=0 update_config=1 network={ # key_mgmt=NONE ssid="xxx" # wifi名 psk="xxx" # 密码 } init-ifupdown:wifi开机自启脚本devtool modify -x init-ifupdown修改meta-mylayer/sources/init-ifupdown/interfaces,添加下面语句:auto wlan0 设置静态IP. IP地址默认是动态分配不是固定的,经常变化导致原有的ssh配置失效,可以通过配置固定IP地址。修改meta-mylayer/sources/init-ifupdown/interfaces,添加以下语句: address 192.168.xxx.yyy netmask 255.255.255.0 gateway 192.168.xxx.1 注意:yyy不要和已有的IP冲突 重新编译init-ifupdownbitbake init-ifupdown -c cleansstate bitbake init-ifupdown定制image菜单 查看yocto自带的镜像菜单,基本都是继承自core-image(如core-image-base.bb): 根据上面的语法同样可以自定义image.bb,使用devtool工具创建image.bb:devtool add core-image-base-rpi 会在meta-mylayer目录下自动生成recipes/core-image-base-rpi/core-image-base-rpi.bb,然后在文件中修改成以下内容,其中FEATURES中打开了ssh并且添加了profile工具包:SUMMARY = "A custom rpi image that fully supports profile and ssh" IMAGE_FEATURES += "splash" LICENSE = "MIT" inherit core-image IMAGE_FEATURES += " debug-tweaks ssh-server-openssh tools-profile " 整体的目录结构如下:poky/meta-mylayer$ tree -L 2 -n . ├── appends │ ├── core-image-base-rpi.bbappend │ ├── init-ifupdown_1.0.bbappend │ ├── rpi-cmdline.bbappend │ ├── rpi-config_git.bbappend │ └── wpa-supplicant_2.10.bbappend ├── conf │ └── layer.conf ├── README ├── recipes │ └── core-image-base-rpi └── sources ├── init-ifupdown ├── rpi-cmdline ├── rpi-config └── wpa-supplicant编译及烧录镜像cd xx/poky source oe-init-build-env rpi-build bitbake core-image-base-rpi 在路径rpi-build/tmp/deploy/images/raspberrypi4会生成镜像文件,烧录可参考上篇。 FAQ烧录不成功 可能是image有问题,也可能是U盘分区或者vmware驱动问题。本人在烧录过程中多次遇到烧录后启动失败现象,可以尝试重启vmware、重新格式化U盘、cleansstate重新编译镜像手段。yocto编译过程失败 一般是由于被墙原因,本人编译时发现部分软件中午下载比较快,晚上较慢。另外可以采用离线的方式,本地下载后复杂到对应的下载目录,网上有教程。修改配置文件后不生效 修改bb后尽量单独要cleansstate后单独bitbake。非不得已不要cleanall,本人实验中曾cleanall,会把下载好的source删除,导致需要重新下载耗时耗力。IMAGE_FEATURES和EXTRA_IMAGE_FEATURES区别 IMAGE_FEATURES用于镜像bb文件中的,可以使用操作符+=进行追加,也可以显示通过IMAGE_FEATURES:append方式,而IMAGE_FEATURES_append写法适用于老版本,新版本不再适用。EXTRA_IMAGE_FEATURES是用于local.conf文件来扩展特性。