By: fu linux
E-mail: fulinux@sina.com
Blog: https://blog.csdn.net/fulinus
喜欢的盆友欢迎点赞和订阅!
你的喜欢就是我写作的动力!
简单回顾下
继续,上一篇我们完成了
zImage
的编译,
但是我们需要将其制作成类似安卓那样的
boot.img
。
上传meta到gitee
比如可以自己在gitee上创建一个新的meta-mybsp,参考:yocto-第4篇-创建自己的meta layer
- 下载源码和添加layer
poky]$ git clone https://gitee.com/fulinux/meta-mybsp.git #使用自己的meta-mybsp
poky]$ source oe-init-build-env
build]$ bitbake-layers add-layer ../meta-mybsp #加入conf/bblayers.conf中
- 1
- 2
- 3
-
然后,将内核拷贝到recipe目录中:
我之前有说过我们内核是需要自备的哈,我就没有上传上去,请知悉~
build]$ cd ../meta-mybsp/
meta-mybsp]$ cp <you kernel path> recipes-kernel/linux-msm/ -rf
- 1
- 2
- 修改build/conf/local.conf:
poky]$ vim build/conf/local.conf
MACHINE ?= "msm8909"
PACKAGE_CLASSES ?= "package_ipk" #有可能你的机器不需要修改哦
- 1
- 2
- 3
- 重新source环境,再编译
poky]$ source oe-init-build-env
build]$ bitbake core-image-minimal
ERROR: Unable to start bitbake server (None)
ERROR: Server log for this session (/home/peeta/poky/build/bitbake-cookerdaemon.log):
--- Starting bitbake server pid 30365 at 2021-04-01 19:00:06.842137 ---
ERROR: Layer meta-mybsp is not compatible with the core layer which only supports these series: dunfell (layer is compatible with gatesgarth)
- 1
- 2
- 3
- 4
- 5
- 6
上面编译失败了
-
修复编译问题
这个主要是meta-bsp
中的meta-mybsp/conf/layer.conf
配置不兼容问题导致的,修改如下:
#LAYERSERIES_COMPAT_meta-mybsp = "gatesgarth" #禁用这个兼容配置,当前我的是dunfell,但是我觉得经常改,还不如不要这个设置
- 1
- 再次编译
build]$ bitbake core-image-minimal #通用的镜像,就暂时不用考虑文件系统的问题了,这个是迷你版
- 1
这个过程是不是so easy, 我也只是将这个过程演示给大家看,方便大家能够容易上手,遇到具体问题需要具体分析。
编译过程发现好多这些警告:
NOTE: preferred version 3.18 of linux-msm not available (for item kernel-module-raid1)
NOTE: versions of linux-msm available: 3.18.71
- 1
- 2
是不是很烦~ 也很简单,修改如下:
meta-mybsp] vim conf/machine/msm8909.conf
PREFERRED_VERSION_linux-msm ?= "3.18%"
- 1
- 2
制作boot.img
好了开始制作我们的
boot.img
之旅。
之所以需要将内核制作成
boot.img
,是因为bootloader(
lk
)需要吧!没确认~
添加mkbootimg-native的recipe
高通制作
boot.img
需要用到
zImage
和
mkbootimg
工具,zImage已经完成了,现在添加
mkbootimg
工具。因为该工具是在
ubuntu/linux
编译机器上运行的,所以后面通常有recipe后面通常带
native
关键词,并将其放到开发工具类的
recipes-devtools
目录中:
meta-mybsp]$ mkdir -p recipes-devtools/mkbootimg
meta-mybsp]$ cp <some path>/mkbootimg/ recipes-devtools/mkbootimg/ -rf #后续我直接提交到gitee上去
meta-mybsp]$ ls recipes-devtools/mkbootimg/mkbootimg/
Android.mk bootimg.h makefile mkbootimg.c
- 1
- 2
- 3
- 4
工具还是挺简单的就一个源码和头文件。现在添加bb文件:
meta-mybsp]$ vim recipes-devtools/mkbootimg/mkbootimg-native_git.bb
# mkbootimg-native
inherit native #继承了native,就告诉了yocto这个是编译机运行的,在build/tmp/work/x86_64-linux目录下
#这下面一大坨就不看了,就是license和说明啥的。
DESCRIPTION = "Boot image creation tool from Android"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/\
${LICENSE};md5=89aea4e17d99a7cacdbeed46a0096b10"
HOMEPAGE = "http://android.git.kernel.org/?p=platform/system/core.git"
PROVIDES = "mkbootimg-native" #一个别名列表,通过它可以知道一个特定的recipe,就像前面的virtual/kernel
FILESEXTRAPATHS_prepend := "${THISDIR}/:" #指定文件搜索的路径(扩展构建系统在处理recipe和bbappend文件时查找文件和补丁时使用的搜索路径),就是当前bb文件所在目录加进这个变量了, 并且在其他目录前面,优先搜索
SRC_DIR = "mkbootimg" #源码目录,这个变量加上
SRC_URI = "file://mkbootimg/" #本地或远程的源文件的列表, 很多项目源码我都直接放在recipe目录里面了,主要是有时候在源码和bb文件直接切换太麻烦了,所以放一起了,根据需要可以放在其他地方哈。
S = "${WORKDIR}/mkbootimg" #bitbake -e mkbootimg | grep ^S=就知道什么意思了
DEPENDS = "libmincrypt-native" #还需要依赖这个recipe,需要在编译这个之前完成这个recipe
PR = "r6" #这个要不要无所谓
MY_PN = "mkbootimg" #自定义
#指定编译参数,头文件和静态库,因为这个是一个makefile文件的项目,需要指定编译器CC
EXTRA_OEMAKE = "INCLUDES='-Imincrypt' LIBS='${libdir}/libmincrypt.a'"
EXTRA_OEMAKE += "CC=${CC}"
do_configure[noexec]="1" #这个是一个makefile文件的项目,没有配置阶段
do_install() { #重定义安装任务
install -d ${D}${bindir} #创建这个目录
install ${MY_PN} ${D}${bindir} #相当于复制:cp mkbootimg ${D}${bindir}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
添加libmincrypt-native的recipe
libmincrypt字面意思是迷你的加密库。
- 创建recipe目录和复制源码
meta-mybsp]$ mkdir -p recipes-devtools/libmincrypt/
meta-mybsp]$ cp -rf <some path>/libmincrypt/ recipes-devtools/libmincrypt/
meta-mybsp]$ cd recipes-devtools/libmincrypt/
- 1
- 2
- 3
- 创建recipe的bb文件
libmincrypt]$ vim libmincrypt-native_git.bb
# libmincrypt-native
inherit native autotools pkgconfig externalsrc #这里面重点就是native,说明是在编译机器上运行的库
DESCRIPTION = "Minimalistic encryption library from Android"
HOMEPAGE = "http://developer.android.com/"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/\
${LICENSE};md5=89aea4e17d99a7cacdbeed46a0096b10"
PR = "r1"
EXTERNALSRC = "${THISDIR}/libmincrypt"
EXTRA_OECONF = " --with-core-includes=${S}/"
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
后记:使用导入外部代码,会在编译的时候在我的源码目录中生成一些其他文件,导致我的git经常发生变动:
modified: libmincrypt/autom4te.cache/output.0
modified: libmincrypt/autom4te.cache/output.1
...
modified: libmincrypt/ltmain.sh
- 1
- 2
- 3
- 4
因此,这里修改该bb文件,如下:
libmincrypt]$ vim libmincrypt-native_git.bb
# libmincrypt-native
inherit native autotools pkgconfig
DESCRIPTION = "Minimalistic encryption library from Android"
HOMEPAGE = "http://developer.android.com/"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/\
${LICENSE};md5=89aea4e17d99a7cacdbeed46a0096b10"
PR = "r1"
FILESEXTRAPATHS_prepend := "${THISDIR}/:"
SRC_DIR = "libmincrypt"
SRC_URI = "file://libmincrypt/"
S = "${WORKDIR}/libmincrypt"
EXTRA_OECONF = " --with-core-includes=${S}/"
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 编译和简单验证
build]$ bitbake libmincrypt-native
build]$ file ../meta-mybsp/recipes-devtools/libmincrypt/libmincrypt/oe-workdir/image/home/peeta/poky/build/tmp-msm8909/work/x86_64-linux/libmincrypt-native/git-r1/recipe-sysroot-native/usr/lib/libmincrypt.so.0.0.0
../meta-mybsp/recipes-devtools/libmincrypt/libmincrypt/oe-workdir/image/home/peeta/poky/build/tmp-msm8909/work/x86_64-linux/libmincrypt-native/git-r1/recipe-sysroot-native/usr/lib/libmincrypt.so.0.0.0: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=eebf1e2e3edb8147c8151c6297635e6a78c19a01, not stripped
- 1
- 2
- 3
重点: ELF 64-bit LSB shared object, x86-64 。
- 准备好libmincrypt项目后开始编译mkboot-native
build]$ bitbake mkbootimg-native
...
g++: error: /home/peeta/poky/build/tmp-msm8909/work/x86_64-linux/mkbootimg-native/git-r6/recipe-sysroot-native/usr/lib/libmincrypt.a: No such file or directory
...
- 1
- 2
- 3
- 4
不过报错了,看下为什么没有这个“文件”,具体看下:
build]$ ls /home/peeta/poky/build/tmp-msm8909/work/x86_64-linux/mkbootimg-native/git-r6/recipe-sysroot-native/usr/lib/
libltdl.so libltdl.so.7 libltdl.so.7.3.1 libmincrypt.so libmincrypt.so.0 libmincrypt.so.0.0.0 pkgconfig
- 1
- 2
显然只有动态库,没有静态库。
为什么是静态库?要知道linux类的服务器上运行的程序依赖的库都是需要到/usr/lib或者/lib/查找,或者通过设置库路径的环境变量。我们yocto如果要在编译的过程中安装库显然是不合理的,或者设置环境变量也是不合适的,那么这里就可以通过静态库编译进程序中。
不过,在修改成静态库之前我想先试试看能否修改成动态库:
meta-mybsp]$ vim recipes-devtools/mkbootimg/mkbootimg-native_git.bb
#屏蔽下面这句话
#EXTRA_OEMAKE = "INCLUDES='-Imincrypt' LIBS='${libdir}/libmincrypt.a'"
#添加下面这句话
EXTRA_OEMAKE = "INCLUDES='-Imincrypt' LIBS='-lmincrypt'"
- 1
- 2
- 3
- 4
- 5
- 再次编译mkbootimg-native
build]$ bitbake mkbootimg-native
#编译成功
- 1
- 2
- 验证mkbootimg程序:
build]$ file tmp-msm8909/work/x86_64-linux/mkbootimg-native/git-r6/image/home/peeta/poky/build/tmp-msm8909/work/x86_64-linux/mkbootimg-native/git-r6/recipe-sysroot-native/usr/bin/mkbootimg
tmp-msm8909/work/x86_64-linux/mkbootimg-native/git-r6/image/home/peeta/poky/build/tmp-msm8909/work/x86_64-linux/mkbootimg-native/git-r6/recipe-sysroot-native/usr/bin/mkbootimg: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /home/peeta/poky/build/tmp-msm8909/sysroots-uninative/x86_64-linux/lib/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=44e32c6abf2f477aefa2d0b0613449e772cbd1d4, not stripped
build]$ ./tmp-msm8909/work/x86_64-linux/mkbootimg-native/git-r6/image/home/peeta/poky/build/tmp-msm8909/work/x86_64-linux/mkbootimg-native/git-r6/recipe-sysroot-native/usr/bin/mkbootimg
error: no output filename specified
usage: mkbootimg
--kernel <filename>
--ramdisk <filename>
[ --second <2ndbootloader-filename> ]
[ --cmdline <kernel-commandline> ]
[ --board <boardname> ]
[ --base <address> ]
[ --pagesize <pagesize> ]
[ --ramdisk_offset <ramdisk_offset> ]
[ --dt <filename> ]
[ --tags-addr <address> ]
-o|--output <filename>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
说明单独编译mkbootimg程序也是OK的,没有出现动态库找不到的问题,我们就不费那个劲去编译静态库了。
应该是x86_64-linux/lib/ld-linux-x86-64.so.2加载动态库的工具做了这方面工作。
-
在kernel的recipe文件中添加mkbootimg依赖
因为我们需要在kernel的recipe中使用mkbootimg-native
recipe将zImage制作成boot.img
,因此需要添加相应的依赖,如下:
meta-mybsp]$ vim recipes-kernel/linux-msm/linux-msm_3.18.bb
...
inherit kernel kernel-yocto
DEPENDS_append = "mkbootimg-native" #添加该行
...
- 1
- 2
- 3
- 4
- 5
编译后可以看到这个:
build]$ cd tmp-msm8909/work/msm8909-poky-linux-gnueabi/linux-msm/3.18.71-r0/
[peeta@peeta-OptiPlex-7050 3.18.71-r0]$ find -iname mkbootimg
./recipe-sysroot-native/usr/bin/mkbootimg
- 1
- 2
- 3
8.在do_install_append函数中添加mkbootimg命令
do_install_append() {
mkbootimg --kernel ${D}/${KERNEL_IMAGEDEST}/${KERNEL_IMAGETYPE}-${KERNEL_VERSION} \
--ramdisk /dev/null \
--cmdline "${KERNEL_CMD_PARAMS}" \
--pagesize ${PAGE_SIZE} \
--base ${KERNEL_BASE} \
--ramdisk_offset 0x0 \
${extra_mkbootimg_params} --output ${D}/${KERNEL_IMAGEDEST}/${BOOTIMAGE_TARGET}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
可见上面使用mkbootimg前面不需要加任何的路径即可执行,这个太棒了!
其中
${D}/${KERNEL_IMAGEDEST}/${KERNEL_IMAGETYPE}-${KERNEL_VERSION}
指向的就是
/home/peeta/poky/build/tmp-msm8909/work/msm8909-poky-linux-gnueabi/linux-msm/3.18.71-r0/image/boot/zImage-3.18.71
使用到了
KERNEL_CMD_PARAMS
变量,在
msm8909.conf
定义如下:
KERNEL_CMD_PARAMS = "noinitrd console=ttyHSL0,115200,n8 androidboot.hardware=qcom ehci-hcd.park=3 msm_rtb.filter=0x37 lpm_levels.sleep_disabled=1 rootwait androidboot.bootdevice=7824900.sdhci"
- 1
其中PAGE_SIZE、KERNEL_BASE、BOOTIMAGE_TARGET三个变量未定义,我们在config文件中定义如下:
meta-mybsp]$ vim conf/machine/msm8909.conf
PAGE_SIZE ?= "4096" #页通常是4K
KERNEL_BASE ?= "0x81C00000" #这个是内核加载到DRAM中的起始地址吧~
BOOTIMAGE_TARGET ?= "${MACHINE}-boot.img" #输出的镜像名,前面加了一个机器名msm8909
- 1
- 2
- 3
- 4
还有这个
extra_mkbootimg_params
变量,主要是预留这个后期扩展使用,现在空着不管不顾。
- 编译过程遇到这个问题:
NOTE: Executing Tasks
ERROR: linux-msm-3.18.71-r0 do_package: QA Issue: linux-msm: Files/directories were installed but not shipped in any package:
/boot/msm8909-boot.img
Please set FILES such that these items are packaged. Alternatively if they are unneeded, avoid installing them or delete them within do_install.
linux-msm: 1 installed and not shipped files. [installed-vs-shipped]
ERROR: linux-msm-3.18.71-r0 do_package: Fatal QA errors found, failing task.
ERROR: Logfile of failure stored in: /home/peeta/poky/build/tmp-msm8909/work/msm8909-poky-linux-gnueabi/linux-msm/3.18.71-r0/temp/log.do_package.26642
ERROR: Task (/home/peeta/poky/meta-mybsp/recipes-kernel/linux-msm/linux-msm_3.18.bb:do_package) failed with exit code '1'
NOTE: Tasks Summary: Attempted 509 tasks of which 493 didn't need to be rerun and 1 failed.
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
错误提示说安装了一个没有shipped的文件,就是msm8909-boot.img文件,该如何处理呢?
不过也给了提示,让我们设置FILES和[installed-vs-shipped],于是我们在bb文件中添加如下内容:
FILES_${PN} += "/${KERNEL_IMAGEDEST}/${BOOTIMAGE_TARGET}"
INSANE_SKIP_${PN} := "installed-vs-shipped"
- 1
- 2
- 再次编译执行成功:
build]$ ls tmp-msm8909/work/msm8909-poky-linux-gnueabi/linux-msm/3.18.71-r0/image/boot/
config-3.18.71 msm8909-boot.img vmlinux-3.18.71
Module.symvers-3.18.71 System.map-3.18.71 zImage-3.18.71
- 1
- 2
- 3
生成了我们需要的
msm8909-boot.img
镜像文件。
不过在
tmp-msm8909/deploy/images/msm8909/
目录中没有
msm8909-boot.img
镜像文件
build]$ ls tmp-msm8909/deploy/images/msm8909/
modules--3.18.71-r0-msm8909-20210407122010.tgz zImage
modules-msm8909.tgz zImage--3.18.71-r0-msm8909-20210407122010.bin
zImage-msm8909.bin
- 1
- 2
- 3
- 4
- 可以通过do_deploy函数中进行安装:
do_deploy_append() {
install -d ${DEPLOY_DIR_IMAGE}
install ${D}/${KERNEL_IMAGEDEST}/${BOOTIMAGE_TARGET} ${DEPLOY_DIR_IMAGE}
install ${D}/${KERNEL_IMAGEDEST}/vmlinux-${KERNEL_VERSION} ${DEPLOY_DIR_IMAGE} #vmlinux对于高通抓dump有用,也导出来
}
- 1
- 2
- 3
- 4
- 5
编译后就有了:
build]$ bitbake virtual/kernel
build]$ ls tmp-msm8909/deploy/images/msm8909/
modules--3.18.71-r0-msm8909-20210408105958.tgz zImage
modules-msm8909.tgz zImage--3.18.71-r0-msm8909-20210408105958.bin
msm8909-boot.img zImage-msm8909.bin
vmlinux-3.18.71
- 1
- 2
- 3
- 4
- 5
- 6
刷机跑一跑进行验证
- 刷机
C:\Users\peeta.chen>fastboot flash boot U:\poky\build\tmp-msm8909\deploy\images\msm8909\msm8909-boot.img
Sending 'boot' (8524 KB) OKAY [ 0.369s]
Writing 'boot' OKAY [ 0.262s]
Finished. Total time: 0.660s
- 1
- 2
- 3
- 4
不过在bootloader启动阶段解析设备树DTB文件出错了:
[840] Unable to locate /bootselect partition
[850] Loading (boot) image (8728576): start
[910] Loading (boot) image (8728576): done
[920] use_signed_kernel=1, is_unlocked=1, is_tampered=0.
[920] Uncpmpressed kernel in use
[920] Kernel image not patched..Unable to locate dt offset
[940] DTB offset is incorrect, kernel image does not have appended DTB
[940] Device info 0x000000f5/00020000/0x00010008/0, pmic 0x1010d/0x0/0x0/0x0
[950] ERROR: Appended Device Tree Blob not found
[950] ERROR: Could not do normal boot. Reverting to fastboot mode.
[970] battery is not present
[970] fastboot_init()
[970] Loading keystore failed status 5 [1070] USB init ept @ 0x8f6ca000
[1090] udc_start()
[1190] -- reset --
[1190] -- portchange --
[1310] fastboot: processing commands
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
经过一番捣鼓,发现kernel的的镜像类型有个这个类型:
zImage-dtb
[peeta@peeta-OptiPlex-7050 3.18.71]$ grep -i zImage-dtb -r .
arch/arm/Kconfig:1923: The image will built in arch/arm/boot/zImage-dtb
arch/arm/Kconfig:1930: building a concatenated zImage-dtb.
arch/arm/boot/Makefile:70:$(obj)/zImage-dtb: $(obj)/zImage $(DTB_OBJS) FORCE
arch/arm/Makefile:291:KBUILD_IMAGE := zImage-dtb
arch/arm/Makefile:331:zImage-dtb: vmlinux scripts dtbs
- 1
- 2
- 3
- 4
- 5
- 6
大体的意思是zImage和设备树的dtb两个镜像文件是拼接在一起的~
直接和kernel编译在一起,生成zImage-dtb,dtb的位置在kernel起始地址偏移0x2C的位置,然后和kernel一起打包到bootimage里。
https://blog.csdn.net/chenzhen1080/article/details/101000470
-
于是修改msm8909.conf文件中的
KERNEL_IMAGETYPE
,如下:
meta-mybsp]$ vim conf/machine/msm8909.conf
...
KERNEL_IMAGETYPE = "zImage-dtb"
- 1
- 2
- 3
- 再次编译,然后刷机
C:\Users\peeta.chen>fastboot flash boot U:\poky\build\tmp-msm8909\deploy\images\msm8909\msm8909-boot.img
Sending 'boot' (19236 KB) OKAY [ 0.821s]
Writing 'boot' OKAY [ 0.539s]
Finished. Total time: 1.392s
C:\Users\peeta.chen>fastboot reboot
Rebooting
Finished. Total time: 0.007s
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
在串口中打印的内容截图:
下一篇讲解如何添加bootloader(或者叫lk)
给我点个赞加个关注呗!万分感谢!