rockchip uboot 应用dts overlays
提供一种基于rkSDK buildroot使用dtbo的方法
简单说明:
- uboot中默认加载
default-dtb-overlay.dtbo
app/dtbo-tools/S03checkDTBO
开机检查拨码开关,并将/boot/overlays/default-dtb-overlay.dtbo
链接到目标dtbo,有效的dtbo名全部存放于dtbo_table
变量中- build.sh中:新增dtbo编译选项,根据
RK_KERNEL_DTS_OVERLAYS
配置自动更新S03checkDTBO
中dtbo_table
变量,并将dtbo与S03checkDTBO
安装到rootfs - 在.BoardConfig 添加
RK_KERNEL_DTS_OVERLAYS
环境变量
uboot补丁
diff --git a/arch/arm/mach-rockchip/boot_rkimg.c b/arch/arm/mach-rockchip/boot_rkimg.c
index 097d976b1f..1ace5da174 100644
--- a/arch/arm/mach-rockchip/boot_rkimg.c
+++ b/arch/arm/mach-rockchip/boot_rkimg.c
@@ -35,6 +35,7 @@
#include <u-boot/sha1.h>
#include <u-boot/sha256.h>
#include <linux/usb/phy-rockchip-usb2.h>
+#include <mapmem.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -552,6 +553,136 @@ static int rkimg_traverse_read_dtb(void *fdt, int where)
return -EINVAL;
}
+static int do_get_ext2(cmd_tbl_t *cmdtp, const char *file_path, char *file_addr)
+{
+ static char *fs_argv[5];
+ disk_partition_t part_info;
+ char part_num[4]= {0};
+
+ int ret = part_get_info_by_name(dev_desc, "rootfs", &part_info);
+ if (ret < 0){
+ printf("[warning] not found partion:%s\n","rootfs");
+ return ret;
+ }
+
+ sprintf(part_num, "%s:%d", env_get("devnum"), ret);
+
+ fs_argv[0] = "ext2load";
+ fs_argv[1] = env_get("devtype");
+ fs_argv[2] = part_num;
+ fs_argv[3] = file_addr;
+ fs_argv[4] = (void *)file_path;
+
+ printf("runcmd: <%s %s %s %s %s>\n",fs_argv[0],fs_argv[1],fs_argv[2],fs_argv[3],fs_argv[4]);
+
+ if (!do_ext2load(cmdtp, 0, 5, fs_argv))
+ return 1;
+ return -ENOENT;
+}
+
+static int get_relfile_envaddr(cmd_tbl_t *cmdtp, const char *file_path, const char *envaddr_name)
+{
+ unsigned long file_addr;
+ char *envaddr;
+ char addr_buf[18];
+
+ envaddr = env_get(envaddr_name);
+
+ if (!envaddr){
+ printf("missing environment variable: %s\n", envaddr_name);
+ return -ENOENT;
+ }
+
+ if (strict_strtoul(envaddr, 16, &file_addr) < 0)
+ return -EINVAL;
+
+ sprintf(addr_buf, "%lx", file_addr);
+
+ return do_get_ext2(cmdtp, file_path, addr_buf);
+}
+
+static void kernel_fdt_overlay_apply( char *fdtoverlay)
+{
+ struct fdt_header *working_fdt;
+ char *fdtoverlay_addr_env;
+ ulong fdtoverlay_addr;
+ ulong fdt_addr;
+ int err;
+
+ /* Get the main fdt and map it */
+ fdt_addr = simple_strtoul(env_get("fdt_addr_r"), NULL, 16);
+ working_fdt = map_sysmem(fdt_addr, 0);
+ err = fdt_check_header(working_fdt);
+ if (err){
+ printf("Invalid fdt_addr_r for loading dtb\n");
+ return;
+ }
+ /* Get the specific overlay loading address */
+ env_set("fdtoverlay_addr_r","0x08000000");
+ fdtoverlay_addr_env = env_get("fdtoverlay_addr_r");
+ if (!fdtoverlay_addr_env) {
+ printf("Invalid fdtoverlay_addr_r for loading overlays\n");
+ return;
+ }
+
+ fdtoverlay_addr = simple_strtoul(fdtoverlay_addr_env, NULL, 16);
+
+ /* Cycle over the overlay files and apply them in order */
+ do {
+ struct fdt_header *blob;
+ char *overlayfile;
+ char *end;
+ int len;
+
+ /* Drop leading spaces */
+ while (*fdtoverlay == ' ')
+ ++fdtoverlay;
+
+ /* Copy a single filename if multiple provided */
+ end = strstr(fdtoverlay, " ");
+ if (end) {
+ len = (int)(end - fdtoverlay);
+ overlayfile = malloc(len + 1);
+ strncpy(overlayfile, fdtoverlay, len);
+ overlayfile[len] = '\0';
+ } else
+ overlayfile = fdtoverlay;
+
+ if (!strlen(overlayfile))
+ goto skip_overlay;
+
+ /* Load overlay file */
+ err = get_relfile_envaddr(NULL, overlayfile,
+ "fdtoverlay_addr_r");
+ if (err < 0) {
+ printf("Failed loading overlay %s\n", overlayfile);
+ goto skip_overlay;
+ }
+
+ /* Resize main fdt */
+ fdt_shrink_to_minimum(working_fdt, 8192);
+
+ blob = map_sysmem(fdtoverlay_addr, 0);
+ err = fdt_check_header(blob);
+ if (err) {
+ printf("Invalid overlay %s, skipping\n",
+ overlayfile);
+ goto skip_overlay;
+ }
+
+ err = fdt_overlay_apply_verbose(working_fdt, blob);
+ if (err) {
+ printf("Failed to apply overlay %s, skipping\n",
+ overlayfile);
+ goto skip_overlay;
+ }
+
+skip_overlay:
+ if (end)
+ free(overlayfile);
+ } while ((fdtoverlay = strstr(fdtoverlay, " ")));
+}
+
int rockchip_read_dtb_file(void *fdt)
{
int locate, ret;
@@ -584,7 +715,7 @@ int rockchip_read_dtb_file(void *fdt)
#if defined(CONFIG_ANDROID_BOOT_IMAGE) && defined(CONFIG_OF_LIBFDT_OVERLAY)
android_fdt_overlay_apply((void *)fdt);
#endif
-
+ kernel_fdt_overlay_apply("/boot/overlays/default-dtb-overlay.dtbo");
return 0;
}
#endif
build.sh 补丁
+function build_kernel_dtbo(){
+
+ fs_overlay_dir="$TOP_DIR/buildroot/board/rockchip/rk356x/huaqi/fs-overlay"
+ fs_dtbo_dir="$fs_overlay_dir/boot/overlays"
+ kernel_dts_dir="$TOP_DIR/kernel/arch/arm64/boot/dts/rockchip"
+ DTC="dtc-1.6.0"
+ dtbo_tools="$TOP_DIR/app/dtbo-tools/S03checkDTBO"
+
+ if [ -z "$RK_KERNEL_DTS_OVERLAYS" ];then
+ echo "Don't set RK_KERNEL_DTS_OVERLAYS, exit ..."
+ rm $fs_overlay_dir/etc/init.d/S03checkDTBO
+ rm $fs_overlay_dir/boot -r
+ return
+ fi
+
+ cd $kernel_dts_dir
+ echo "cd $kernel_dts_dir"
+
+ for dts in $RK_KERNEL_DTS_OVERLAYS
+ do
+ if [ -e "$dts.dts" ];then
+ $DTC -I dts -O dtb $dts.dts -o $dts.dtbo
+ if [ "$?" = "0" ];then
+ echo "[DTC] $dts.dtbo"
+ fi
+ dtbo_table="$dtbo_table $dts.dtbo"
+ else
+ echo "[DTC] $dts.dtbo failed,no such file $dts.dts"
+ fi
+ done
+
+ if [ -e "$fs_overlay_dir" ];then
+ mkdir -p "$fs_dtbo_dir"
+ fi
+
+ echo "Install `ls *.dtbo` to $fs_dtbo_dir"
+
+
+ cp $kernel_dts_dir/*.dtbo $fs_dtbo_dir
+
+ if [ -e "$dtbo_tools" ];then
+ sed "s/dtbo_table=/dtbo_table=($dtbo_table)/g" $dtbo_tools > $fs_overlay_dir/etc/init.d/S03checkDTBO
+ echo "Install $dtbo_tools to $fs_overlay_dir/etc/init.d/S03checkDTBO"
+ chmod +x $fs_overlay_dir/etc/init.d/S03checkDTBO
+ cat $fs_overlay_dir/etc/init.d/S03checkDTBO | grep "dtbo_table="
+ else
+ echo "[WARN]: Not found $dtbo_tools!!!"
+ fi
+
+ finish_build
+}
+
function build_kernel(){
check_config RK_KERNEL_DTS RK_KERNEL_DEFCONFIG || return 0
@@ -670,8 +723,9 @@ function build_kernel(){
fi
build_check_power_domain
-
finish_build
+
+ build_kernel_dtbo
}
function build_modules(){
@@ -1015,6 +1069,7 @@ function build_all(){
check_security_condition
build_loader
build_kernel
+ build_kernel_dtbo
build_toolchain
build_rootfs ${RK_ROOTFS_SYSTEM:-buildroot}
build_recovery
@@ -1272,6 +1327,7 @@ for option in ${OPTIONS}; do
uefi) build_uefi ;;
loader) build_loader ;;
kernel) build_kernel ;;
+ dtbo) build_kernel_dtbo;;
modules) build_modules ;;
rootfs|buildroot|debian|yocto) build_rootfs $option ;;
pcba) build_pcba ;;
BoardConfig-rk3568-evb1-ddr4-v10.mk 中新增环境变量
+export RK_KERNEL_DTS_OVERLAYS="rk3568-test rk3568-test2 rk3568-test3 rk3568-test4"
app/dtbo-tools/S03checkDTBO
在build.sh
中根据RK_KERNEL_DTS_OVERLAYS
配置自动更新dtbo_table
#!/bin/sh
### BEGIN INIT INFO
# Provides: check device tree overlay plugin
# Required-Start:
# Required-Stop:
# Default-Start: S
# Default-Stop:
### END INIT INFO
OverlaysPath="/boot/overlays"
OverlaysHeader="rk3568-huaqi-overlays"
dtbo_table=
EXE_NAME=$0
switchGPIO="28 29 30"
function log()
{
logger -s -t "[$EXE_NAME]" $@
}
function getSwichValue(){
for i in $switchGPIO
do
value="$value`gpioget -l 2 $i`"
done
val_hex=$(printf "%02x" $((2#$value)))
echo "0x$val_hex"
}
start() {
log "checkDTBO start ..."
if [ -d "$OverlaysPath" ];then
cd $OverlaysPath
else
log "Not found dir:$OverlaysPath,skip check device tree overlay!!!"
fi
if [ -z "${dtbo_table[0]}" ];then
log "dtbo_table is empty,skip check device tree overlay!!!"
return
fi
OLD_DTBO=`readlink default-dtb-overlay.dtbo`
let swichValue="`getSwichValue`"
if [ $swichValue -gt ${#dtbo_table[@]} ];then
log "dtbo_table[0-${#dtbo_table[@]}]:<${dtbo_table[@]}>"
log "Not define dtbo_table[$swichValue],exit..."
return
fi
NEW_DTBO=${dtbo_table[$swichValue]}
if [ ! -e "$NEW_DTBO" ];then
log "No such file:$NEW_DTBO"
log "skip set default-dtb-overlay.dtbo link to $NEW_DTBO!!!"
return
fi
if [ "$OLD_DTBO" != "$NEW_DTBO" ];then
log "set default-dtb-overlay.dtbo link to $NEW_DTBO"
ln -sf $NEW_DTBO default-dtb-overlay.dtbo
sync
reboot
fi
}
stop() {
echo "checkDTBO stop ..."
}
restart() {
echo "checkDTBO restart ..."
stop
start
}
case "$1" in
start|stop|restart)
"$1";;
reload)
# Restart, since there is no true "reload" feature.
restart;;
*)
echo "Desc: Check device tree overlay plugin script"
echo "Usage: $0 {start|stop|restart|reload}"
exit 1
esac