官方文档
https://wiki.t-firefly.com/zh_CN/ROC-RK3588S-PC/linux_compile_debian.html
目录
整编过程中遇到的问题
- 1.网上下载依赖库一直没有反应
在源码的根目录下,会有一个br.log文件,记录着详细的编译异常日志,包括下载依赖库。
了解一下buildroot编译框架,发现下载的包都在buildroot/dl
目录下,新建一个文件夹名字为库的名字,观看已经下载下来的包的格式,到github上找到这个库然后下载下来放到这个以库同名的文件夹下。
直接把github开头的链接进行下载即可
- 2.dl下的库已经手动下载替换了,build时还是会去下载然后卡在那里。
把buildroot/package下的这个文件夹alsa-ucm-conf下的mk文件删除掉(注意不要删除整个文件夹,否则后面build的时候会报找不到这个库的Config.in文件导致编译失败),重新build则会去下载别的库。
整编脚本解析
- envsetup.sh
作用:为buildroot的Makefile选择一个目标config
function main()
{
#查找buildroot/configs目录下所有以rockchip_的开头的文件名,并将文件名最后的_defconfig字符串去掉。
RK_DEFCONFIG_ARRAY=(
$(cd ${BUILDROOT_DIR}/configs/; ls rockchip_* | \
sed "s/_defconfig$//" | grep "$1" | sort)
)
unset RK_BUILD_CONFIG
RK_DEFCONFIG_ARRAY_LEN=${#RK_DEFCONFIG_ARRAY[@]}
case $RK_DEFCONFIG_ARRAY_LEN in
0)
echo No available configs${1:+" for: $1"}
;;
1)
RK_BUILD_CONFIG=${RK_DEFCONFIG_ARRAY[0]}
;;
*)
#如果在执行envsetup.sh时指定板子的配置模板,就不选择。
if [ "$1" = ${RK_DEFCONFIG_ARRAY[0]} ]; then
# Prefer exact-match
RK_BUILD_CONFIG=$1
else
choose_board
fi
;;
esac
[ -n "$RK_BUILD_CONFIG" ] || return
#这里的.BoardConfig.mk是一个链接文件,指向lunch指令选择的板子配置文件。
#将环境变量加入shell环境
source ${TOP_DIR}/device/rockchip/.BoardConfig.mk
lunch_rockchip
# Set alias
alias croot="cd ${TOP_DIR}"
alias broot="cd ${BUILDROOT_DIR}"
alias bpkg="cd ${BUILDROOT_DIR}/package"
alias bout="cd ${TARGET_OUTPUT_DIR}"
}
/buildroot/configs
function choose_board()
{
echo
echo "You're building on Linux"
echo "Lunch menu...pick a combo:"
echo ""
echo "0. non-rockchip boards"
echo ${RK_DEFCONFIG_ARRAY[@]} | xargs -n 1 | sed "=" | sed "N;s/\n/. /"
local INDEX
while true; do
read -p "Which would you like? [0]: " INDEX
#index如果没有输入,默认为0,再减去1.也就是-1为index的默认值
INDEX=$((${INDEX:-0} - 1))
#没有选择
if [ "$INDEX" -eq -1 ]; then
echo "Lunching for non-rockchip boards..."
unset TARGET_OUTPUT_DIR
unset RK_BUILD_CONFIG
break;
fi
if echo $INDEX | grep -vq [^0-9]; then
RK_BUILD_CONFIG="${RK_DEFCONFIG_ARRAY[$INDEX]}"
[ -n "$RK_BUILD_CONFIG" ] && break
fi
echo
echo "Choice not available. Please try again."
echo
done
}
function lunch_rockchip()
{
TARGET_DIR_NAME="$RK_BUILD_CONFIG"
export TARGET_OUTPUT_DIR="$BUILDROOT_OUTPUT_DIR/$TARGET_DIR_NAME"
mkdir -p $TARGET_OUTPUT_DIR || return
echo "==========================================="
echo
#打印_后字符串
echo "#TARGET_BOARD=`echo $RK_BUILD_CONFIG | cut -d '_' -f 2`"
echo "#OUTPUT_DIR=output/$TARGET_DIR_NAME"
echo "#CONFIG=${RK_BUILD_CONFIG}_defconfig"
echo
echo "==========================================="
# RK_BUILD_CONFIG就是前面执行./envsetup.sh时选择的combo,如rockchip_rk3588.
# 此处make会执行/buildroot目录下的Makefile文件,-C表示进入buildroot目录下,O=表示将编译结果输出到$TARGET_OUTPUT_DIR变量下,
# 最后一个参数表示编译目标为rockchip_rk3588_defconfig
# TAG(A)
make -C ${BUILDROOT_DIR} O="$TARGET_OUTPUT_DIR" \
"$RK_BUILD_CONFIG"_defconfig
# 上面的命令执行完毕,会在builtroot目录下生成.config文件。
CONFIG=${TARGET_OUTPUT_DIR}/.config
# 复制.config文件为.config.new文件。
cp ${CONFIG}{,.new}
# 如果.config.old文件不存在return,否则将.config.old重命名为.config文件.
mv ${CONFIG}{.old,} &>/dev/null || return 0
# 根据当前的.config(old config)重新生成.config
make -C ${BUILDROOT_DIR} O="$TARGET_OUTPUT_DIR" olddefconfig &>/dev/null
# 如果新生成的.config与(old config)生成的.config文件不一致,则提示是否覆盖旧的config。
if ! diff ${CONFIG}{,.new}; then
read -t 10 -p "Found old config, override it? (y/n):" YES
[ "$YES" = "n" ] || cp ${CONFIG}{.new,}
fi
}
对上面TAG(A)的流程进行分析
make -C ${BUILDROOT_DIR} O="$TARGET_OUTPUT_DIR" \ "$RK_BUILD_CONFIG"_defconfig
,编译目标为rockchip_rk3588_defconfig.
1.实际Makefile是没有rockchip_rk3588_defconfig这个目标的,采用的是一种通用的写法。
Makefile的最后面:.PHONY: $(noconfig_targets)
1-1)接着分析BUILD_DIR
变量是如何赋值的
ifneq ("$(origin O)", "command line")
ifneq ($(TARGET_OUTPUT_DIR),)
O := $(TARGET_OUTPUT_DIR)
else
O := $(CURDIR)/output
endif
endif
# Remove the trailing '/.' from $(O) as it can be added by the makefile wrapper
# installed in the $(O) directory.
# Also remove the trailing '/' the user can set when on the command line.
override O := $(patsubst %/,%,$(patsubst %.,%,$(O)))
CANONICAL_O := $(shell mkdir -p $(O) >/dev/null 2>&1)$(realpath $(O))
# Make sure O= is passed (with its absolute canonical path) everywhere the
# toplevel makefile is called back.
EXTRAMAKEARGS := O=$(CANONICAL_O)
# Check Buildroot execution pre-requisites here.
ifneq ($(shell umask):$(CURDIR):$(O),$(REQ_UMASK):$(CANONICAL_CURDIR):$(CANONICAL_O))
BASE_DIR := $(CANONICAL_O)
...
BUILD_DIR := $(BASE_DIR)/build
make时定义了变量TARGET_OUTPUT_DIR为/buildroot/output/rockchip_rk3588
,那么
BUILD_DIR即为/buildroot/output/rockchip_rk3588/build
.
$(1):表示/buildroot目录
TOPDIR:表示/buildroot目录
一、依赖文件
$(BUILD_DIR)/buildroot-config/conf $(1)/configs/%_defconfig outputmakefile
:注意这里有3个依赖,前面2个是文件,最后一个outputmakefile是伪目标。
1.conf文件的生成过程
http://xinyiworld.top/wordpress_it/?p=7722
2.outputmakefile伪目标
outputmakefile:
ifeq ($(NEED_WRAPPER),y)
$(Q)$(TOPDIR)/support/scripts/mkmakefile $(TOPDIR) $(O)
endif
可以看到伪目标在TARGET_OUTPUT_DIR目录下生成了Makefile文件。
二、命令
命令1:
$(TOPDIR)/build/defconfig_hook.py -m $(1)/configs/$$@ $(BASE_DIR)/.rockchipconfig
:执行python脚本
打印一下脚本接收的参数:
这个python脚本主要是采用递归的方法,将/buildroot/configs/rockchip_rk3588_defconfig 配置文件及其include的config文件的内容合并到/buildroot/output/rockchip_rk3588/.rockchipconfig 文件里,并且把所有config的BR2_ROOTFS_OVERLAY属性值合并到一起用空格分开,BR2_ROOTFS_OVERLAY代表这些目录下的文件会原封不动的拷贝到/buildroot/output/rockchip_rk3588/target 目录下。
|
命令2:
$$(COMMON_CONFIG_ENV) BR2_DEFCONFIG=$(1)/configs/$$@ $$< --defconfig=$(BASE_DIR)/.rockchipconfig $$(CONFIG_CONFIG_IN)
这个命令有些复杂,先把相关的变量打印直观看一下:
$$(COMMON_CONFIG_ENV) BR2_DEFCONFIG=$(1)/configs/$$@
:设置变量
$$< --defconfig=$(BASE_DIR)/.rockchipconfig $$(CONFIG_CONFIG_IN)
:执行conf,生成.config文件。
最后,再梳理一下lunch_rockchip的流程:
调用源码目录下的Makefile,调用buildroot目录下的Makefile,执行伪目标%_defconfig,生成conf工具并生成.config配置文件。 |
- build.sh
通过./build.sh -h
查看有哪些编译目标选项
如果build.sh不带任何参数,默认执行allsave选项。
OPTIONS="${@:-allsave}"
一般先要执行./build.sh lunch
配置dts,而后再进行各个模块的编译。
这里会将选择的板子型号与/device/rockchip/.BoardConfig.mk建立软连接
/device/rockchip/.BoardConfig.mk
编译日志分析
1.uboot编译日志
./build.sh uboot
会执行build.sh文件中的build_uboot()方法
root@xinyi:/home/xinyi/android/code/Task1-debian/rk3588_source# ./build.sh uboot
processing option: uboot
============Start building uboot============
TARGET_UBOOT_CONFIG=rk3588
=========================================
## make rk3588_defconfig -j16
#
# configuration written to .config
#
scripts/kconfig/conf --silentoldconfig Kconfig
CHK include/config.h
CFG u-boot.cfg
GEN include/autoconf.mk.dep
CFG spl/u-boot.cfg
CFG tpl/u-boot.cfg
GEN spl/include/autoconf.mk
GEN tpl/include/autoconf.mk
GEN include/autoconf.mk
CHK include/config/uboot.release
CHK include/generated/timestamp_autogenerated.h
UPD include/generated/timestamp_autogenerated.h
CHK include/config.h
CFG u-boot.cfg
UPD include/config/uboot.release
CHK include/generated/version_autogenerated.h
UPD include/generated/version_autogenerated.h
CHK include/generated/generic-asm-offsets.h
CHK include/generated/asm-offsets.h
HOSTCC tools/mkenvimage.o
HOSTCC tools/fit_image.o
HOSTCC tools/image-host.o
HOSTCC tools/dumpimage.o
HOSTCC tools/mkimage.o
HOSTCC tools/rockchip/boot_merger.o
HOSTCC tools/rockchip/loaderimage.o
HOSTLD tools/mkenvimage
tools/rockchip/boot_merger.c: In function ‘main’:
tools/rockchip/boot_merger.c:895:11: warning: array subscript 20 is outside array bounds of ‘char[20]’ [-Warray-bounds]
895 | str[len] = 0;
| ~~~~~~~~~^~~
tools/rockchip/boot_merger.c:933:7: note: while referencing ‘name’
933 | char name[MAX_NAME_LEN];
| ^~~~
HOSTLD tools/loaderimage
HOSTLD tools/boot_merger
HOSTLD tools/dumpimage
HOSTLD tools/mkimage
CC arch/arm/cpu/armv8/fwcall.o
CC drivers/usb/gadget/f_fastboot.o
LD arch/arm/cpu/armv8/built-in.o
CC common/main.o
LD common/built-in.o
CC cmd/version.o
LD cmd/built-in.o
CC lib/display_options.o
LD lib/built-in.o
LD drivers/usb/gadget/built-in.o
LD u-boot
OBJCOPY u-boot.srec
OBJCOPY u-boot-nodtb.bin
SYM u-boot.sym
start=$(/home/xinyi/android/code/Task1-debian/rk3588_source/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-nm u-boot | grep __rel_dyn_start | cut -f 1 -d ' '); end=$(/home/xinyi/android/code/Task1-debian/rk3588_source/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-nm u-boot | grep __rel_dyn_end | cut -f 1 -d ' '); tools/relocate-rela u-boot-nodtb.bin 0x00200000 $start $end
make[2]: “arch/arm/dts/rk3588-evb.dtb”已是最新。
CAT u-boot-dtb.bin
MKIMAGE u-boot.img
COPY u-boot.dtb
MKIMAGE u-boot-dtb.img
COPY u-boot.bin
ALIGN u-boot.bin
COPY spl/u-boot-spl.dtb
CC spl/common/spl/spl.o
CC tpl/arch/arm/cpu/armv8/fwcall.o
CC tpl/arch/arm/mach-rockchip/tpl.o
LD tpl/arch/arm/cpu/armv8/built-in.o
CC spl/arch/arm/cpu/armv8/fwcall.o
LD spl/arch/arm/cpu/armv8/built-in.o
LD tpl/arch/arm/mach-rockchip/built-in.o
CC spl/lib/display_options.o
LD spl/lib/built-in.o
LD tpl/u-boot-tpl
LD spl/common/spl/built-in.o
OBJCOPY tpl/u-boot-tpl-nodtb.bin
COPY tpl/u-boot-tpl.bin
LD spl/u-boot-spl
OBJCOPY spl/u-boot-spl-nodtb.bin
CAT spl/u-boot-spl-dtb.bin
COPY spl/u-boot-spl.bin
CFGCHK u-boot.cfg
SEC=1
pack u-boot.itb okay! Input: /home/xinyi/android/code/Task1-debian/rk3588_source/rkbin/RKTRUST/RK3588TRUST.ini
FIT description: FIT Image with ATF/OP-TEE/U-Boot/MCU
Created: Fri Sep 30 15:58:49 2022
Image 0 (uboot)
Description: U-Boot
Created: Fri Sep 30 15:58:49 2022
Type: Standalone Program
Compression: uncompressed
Data Size: 1209856 Bytes = 1181.50 KiB = 1.15 MiB
Architecture: AArch64
Load Address: 0x00200000
Entry Point: unavailable
Hash algo: sha256
Hash value: 0459350cd91ca27a265308d22a864caaf33b1ee98b3614ca76d7ef278d57b169
Image 1 (atf-1)
Description: ARM Trusted Firmware
Created: Fri Sep 30 15:58:49 2022
Type: Firmware
Compression: uncompressed
Data Size: 186688 Bytes = 182.31 KiB = 0.18 MiB
Architecture: AArch64
Load Address: 0x00040000
Hash algo: sha256
Hash value: 5ae6932916e5275236ed293d074bcc75bdea046c36e6c7be147a015bf1d9c0fc
Image 2 (atf-2)
Description: ARM Trusted Firmware
Created: Fri Sep 30 15:58:49 2022
Type: Firmware
Compression: uncompressed
Data Size: 28672 Bytes = 28.00 KiB = 0.03 MiB
Architecture: AArch64
Load Address: 0x000f0000
Hash algo: sha256
Hash value: c00c7fd75b913cf44d12a27e172513124eaeec71b4448b41aa1c295c05907b3f
Image 3 (atf-3)
Description: ARM Trusted Firmware
Created: Fri Sep 30 15:58:49 2022
Type: Firmware
Compression: uncompressed
Data Size: 20480 Bytes = 20.00 KiB = 0.02 MiB
Architecture: AArch64
Load Address: 0xff100000
Hash algo: sha256
Hash value: 71c3a5841b733b001fe1defcc4d268af37dab96c503c4c71c9c5daa714d3fdd5
Image 4 (atf-4)
Description: ARM Trusted Firmware
Created: Fri Sep 30 15:58:49 2022
Type: Firmware
Compression: uncompressed
Data Size: 8192 Bytes = 8.00 KiB = 0.01 MiB
Architecture: AArch64
Load Address: 0xff001000
Hash algo: sha256
Hash value: 2301cf73be91bb638ecd9c296d6674b9d52696a3825745070c92e21e79c8be24
Image 5 (optee)
Description: OP-TEE
Created: Fri Sep 30 15:58:49 2022
Type: Firmware
Compression: uncompressed
Data Size: 461200 Bytes = 450.39 KiB = 0.44 MiB
Architecture: AArch64
Load Address: 0x08400000
Hash algo: sha256
Hash value: 4ed9cd20b57f71e3b751bc9c0129d74c371e5633ed32a89c6ef42b7a22b59fa2
Image 6 (fdt)
Description: U-Boot dtb
Created: Fri Sep 30 15:58:49 2022
Type: Flat Device Tree
Compression: uncompressed
Data Size: 7829 Bytes = 7.65 KiB = 0.01 MiB
Architecture: AArch64
Hash algo: sha256
Hash value: c07f4a4d713c2dde198a1c4fc7a980a98f5dc97665e3171dc7c319d7846dc381
Default Configuration: 'conf'
Configuration 0 (conf)
Description: rk3588-evb
Kernel: unavailable
Firmware: atf-1
FDT: fdt
Loadables: uboot
atf-2
atf-3
atf-4
optee
********boot_merger ver 1.2********
Info:Pack loader ok.
pack loader okay! Input: /home/xinyi/android/code/Task1-debian/rk3588_source/rkbin/RKBOOT/RK3588MINIALL.ini
/home/xinyi/android/code/Task1-debian/rk3588_source/u-boot
Image(no-signed, version=0): uboot.img (FIT with uboot, trust...) is ready
Image(no-signed): rk3588_spl_loader_v1.07.111.bin (with spl, ddr...) is ready
pack uboot.img okay! Input: /home/xinyi/android/code/Task1-debian/rk3588_source/rkbin/RKTRUST/RK3588TRUST.ini
Platform RK3588 is build OK, with new .config(make rk3588_defconfig -j16)
/home/xinyi/android/code/Task1-debian/rk3588_source/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-
Fri Sep 30 15:58:49 CST 2022
Running build_uboot succeeded.
执行流程:
build.sh ---> build_uboot(),进入uboot目录,执行make.sh脚本。
uboot的make.sh脚本执行流程
执行process_args方法
注意此方法是一个参数一个参数地依次执行,第一个参数是rk3588,第二个参数是CROSS_COMPILE=*。
解析第一个参数rk3588
-
》》》执行fit.sh,基本上啥事儿没有干。
-
》》》通过KConfig系统生成uboot的配置文件.config
make rk3588_defconfig
会打印# # configuration written to .config #
在Makefile中对应的目标为:
%config: scripts_basic outputmakefile FORCE
$(Q)$(MAKE) $(build)=scripts/kconfig $@
目标:scripts_basic
scripts_basic:
$(Q)$(MAKE) $(build)=scripts/basic
$(Q)rm -f .tmp_quiet_recordmcount
见http://xinyiworld.top/wordpress_it/?p=8101 可知,$(Q)$(MAKE) $(build)=scripts/basic
相当于执行u-boot/scripts/Makefile.build
中的__build
伪目标,依赖项即为$(always),此变量$(always)通过Makefile.build中include scripts/basic
目录下的Makefile文件,值即为fixdep
目标:fixdep
https://www.pianshen.com/article/8257930864/ (fixdep工具的生成过程)
https://blog.csdn.net/guyongqiangx/article/details/52588409 (fixdep工具的调用)
fixdep是KBuild中一种非常重要的机制,该工具的作用就是在编译过程中产生依赖信息,判断依赖目标是不是更新的。
此处outputmakefile并没有执行任何有效操作
FORCE是强制执行目标的机制
最终执行的是$(Q)$(MAKE) $(build)=scripts/kconfig $@
,即执行scripts/kconfig下的rk3588_defconfig目标:
%_defconfig: $(obj)/conf
$(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)
$(SRCARCH)是..
,最终--defconfig指向的是u-boot/configs/rk3588_defconfig
文件,最终走向了Kbuild系统。
尝试在u-boot里直接运行conf生成配置文件
会报这个错误,不知道是什么个原理。
目标:include/config/%.conf
执行select_toolchain方法
主要是去指定一些prebuilts目录下的交叉编译工具
执行fixup_platform_configure方法
有个方法得关注一下
function filt_val()
{
sed -n "/${1}=/s/${1}=//p" $2 | tr -d '\r' | tr -d '"'
}
这个方法的作用是根据key去.config文件里查找value,并去除回车符、引号。
执行select_ini_file方法
选择.ini文件
0 条评论