Yocto开发相关笔记
- 添加一个新的machine
添加一个新的machine需要在新加layer的conf/machine/目录中填写对应的配置文件,比如:raspberrypi3.conf是树莓派3的配置文件。该配置文件位于meta-raspberrypi/conf/machine/raspberrypi3.conf。
machine的配置文件中一般都包含如下内容:
TARGET_ARCH:指出目标平台架构名称,如:arm
PREFERRED_PROVIDER:指出优先采用的recipe名称。比如:PREFERRED_PROVIDER_virtual/kernel ?= “linux-raspberry”,说明对于kernel的使用,优先采用linux-raspberrypi这个recipe。
MACHINE_FEATURES:指出MACHINE支持的硬件特性,比如:MACHINE_FEATURES = “apm bluetooth wifi screen”
SERIAL_CONSOLE:指出串口的配置,比如:SERIAL_CONSOLE = “115200 ttyS0”
KERNEL_IMAGETYPE:指出linux内核镜像的类型,比如:KERNEL_IMAGETYPE = “zImage”
IMAGE_FSTYPES:指出文件系统镜像的文件系统类型,比如:IMAGE_FSTYPES = “tar.gz jffs2”
- 配置linux内核
使用menuconfig来配置内核。
$bitbake linux-yocto -c kernel_configme -f
$bitbake linux-yocto -c menuconfig
创建defconfig文件来配置内核。
defconfig文件就是kernel的.config文件的更名,将defconfig文件复制到recipe目录中,之后在.bb或.bbappend文件中添加如下内容:
FILESEXTRAPATHS_prepend := “${THISDIR}/${PN}: “
SRC_URI += “file://defconfig”
创建配置分片(configuration fragments)
可以将内核的配置项分散到多个配置文件中,之后将配置文件放置到recipe目录中,最后在.bb或.bbappend文件中添加如下内容:
SRC_URI += “file://myconfig.cfg \
file://ethernet.cfg \
file://gfx.cfg”
OpenEmbedded编译系统会逐个读取出这个分片的内容,之后添加到内核配置文件.config中。
微调内核配置文件
通过调用do_kernel_configme和do_kernel_configcheck任务来微调内核配置文件。
$bitbake linux-yocto -c kernel_configme
$bitbake linux-yocto -c kernel_configcheck
执行完kernel_configcheck后会输出一系列警告或问题,解决之。之后重新执行上述两个命令,直到满意为止。
- kernel打patch
3.1 找到当前内核源代码路径,即:cd ~/poky/build/tmp/work/qemux86-poky-linux/linux-yocto-${PV}-${PR}/linux
3.2 修改内核源代码文件。
3.3 使用git命令提交修改后的内核源代码。
$git status .
$git add .
$git commit -m “xxx”
3.4 创建patch文件。
$git format-path -1
3.5 创建自己的layer。
配置layer的conf目录和recipes-kernel/linux目录
在recipes-kernel/linux目录下创建recipe文件,即:linux-yocto_${PV}.bbappend。之后在文件中添加如下内容:
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
SRC_URI += "file://0001-calibrate-Add-printk-example.patch"
在recipes-kernel/linux目录下创建linux-yocto目录,之后将内核patch文件复制到该目录中
3.6 检查自己的layer的有效性。
在build目录里的conf/bblayer.conf中查看自己的layer是否被添加到BBLAYER变量中
3.7 重新编译内核。
$bitbake -c cleansstate linux-yocto 清空缓存中的内容
$bitbake -k linux-yocto 重新编译内核
- 安全问题
4.1 安全问题的总体考虑。
使用静态分析工具扫描添加到系统中的其它代码;
格外注意基于web的管理员接口;
确保软件的及时更新;
发布版本的时候确保删除或禁用debug功能;
确保发行版本中不会有不需要的网络监听程序;
删除发行版中不必要的软件;
确认硬件上支持secure boot功能;
4.2 Security flags。
若需要Security的编译,则需要在local.conf中添加如下一行:
require conf/distro/include/security_flags.inc
security_flags.inc文件中主要是包含了编译/链接过程中的关于安全的相关选项。
4.3 其它的考虑。
在image中去掉IMAGE_FEATURES或EXTRA_IMAGE_FEATURES=“debug-tweaks”选项
使用extrausers类实现root用户以及其它用户的密码设置
考虑使用Mandatory Access Control(MAC),即:使用meta-selinux层
考虑使用meta-security层
- Packages相关操作
5.1 制作镜像的时候删除包。
使用如下变量实现:
BAD_RECOMMENDATIONS:该变量针对recommended-only包有效;
NO_RECOMMENDATIONS:该变量用于禁止安装所有recommend-only包;
PACKAGE_EXCLUDE:该变量用于禁止指定包的安装;
5.2 制作运行时动态安装包。
在源代码包编译的过程中需要在变量IMAGE_FEATURES中添加package-management;
在服务器端需要添加http等服务;
- Initialization Manager的选择
yocto默认使用SysVinit作为启动器,然而yocto也支持systemd启动方式。若选择systemd则需要如下内容:
设置如下变量启用systemd:
DISTRO_FEATURES_append = “ systemd”
VIRTUAL-RUNTIME_init_manager = “systemd”
此时系统启动的时候默认采用systemd方式启动,但是sysvinit脚本也安装到image中只不过在rescure/minimal中使用sysvinit方式启动
删除SysVinit脚本:
DISTRO_FEATURES_BACKFILL_CONSIDERED = “sysvinit”
- 选择一个设备管理器
设备管理器用于管理/dev目录,设备管理器包括:静态的和动态的。其中静态的在编译过程中确定/dev目录中的内容,之后就不再变化了,而动态的则是实用devtmpfs来管理/dev目录,由内核在启动过程中动态的操作且在用户态空间由udev或者busybox-mdev进程进行处理。
静态管理:
设置USE_DEVFS = “0”
设置IMAGE_DEVICE_TABLES = “device_table_mymachine.txt”设置device tables文件
动态管理:
设置USE_DEVFS = “1”。此时内核采用devtmpfs来初始化/dev目录(在内核配置方面要添加CONFIG_DEVTMPFS);
所有由devtmpfs创建的设备节点属于root用户且访问权限是0600;
设置用户态设备管理进程,即:VIRTUAL-RUNTIME_dev_manager = “udev” 设置设备管理用户态进程为udev;