i.MX8MM处理器采用了先进的14LPCFinFET工艺,提供更快的速度和更高的电源效率;四核Cortex-A53,单核Cortex-M4,多达五个内核 ,主频高达1.8GHz,2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT、4G模块、CAN、RS485等接口一应俱全。H264、VP8视频硬编码,H.264、H.265、VP8、VP9视频硬解码,并提供相关历程,支持8路PDM接口、5路SAI接口、2路Speaker。系统支持Android9.0(支持获取root限)Linux4.14.78+Qt5.10.1、Yocto、Ubuntu20、Debian9系统。适用于智能充电桩,物联网,工业控制,医疗,智能交通等,可用于任何通用工业和物联网应用、
【公众号】迅为电子
第六十九章uboot移植
69.1 编译脚本分析
在第六十七章的内容里面,我们编译生成了flash.bin文件,在生成flash.bin文件的过程中,我们是手动输入命令生成的,但是为了加快测试速度,我们本章节要编写一个自动化脚本。
在第六十七章节,我们已经下载了NXP官方提供的uboot源码,本章节我们要将此源码移植到迅为iTOP-IMX8MM开发板上。在/home/topeet/bsp_kernel_imx目录下新建一个编译脚本build.sh。
BOARD_TYPE=DDR4 /*设置开发板的类型是DDR4 */export MAKE_JOBS=`cat /proc/cpuinfo | grep "processor" | wc -l` /*查看cpu的个数 */echo MAKE_JOBS:$MAKE_JOBSexport SDK_PATH="$PWD" /* SDK_PATH 变量=当前目录的路径 */export ATF_INSTALL_DIR=$SDK_PATH/imx-atf /* ATF_INSTALL_DIR变量=当前目录的路径/imx-atf目录下 */echo ATF_INSTALL_DIR:$ATF_INSTALL_DIR /* 打印 ATF_INSTALL_DIR的安装目录 */export UBOOT_INSTALL_DIR=$SDK_PATH/uboot-imx /* 设置 UBOOT_INSTALL_DIR的安装目录 */
echo UBOOT_INSTALL_DIR:$UBOOT_INSTALL_DIR
if [ $BOARD_TYPE == "DDR4" ]; then /*如果BOARD_TYPE==DDR4*/export UBOOT_DEFCONFIG=imx8mm_ddr4_evk_defconfig/*设置uboot默认的配置文件为imx8mm_ddr4_evk_defconfig*/export UBOOT_DTB=fsl-imx8mm-ddr4-evk.dtb/*设置uboot默认的设备树文件为fsl-imx8mm-ddr4-evk.dtb*/
elseexport UBOOT_DEFCONFIG=imx8mm_evk_defconfig/**/export UBOOT_DTB=fsl-imx8mm-evk.dtb/**/
fiecho UBOOT_DEFCONFIG:$UBOOT_DEFCONFIG/*打印uboot默认的配置文件*/
echo UBOOT_DTB:$UBOOT_DTB/*打印uboot的默认配置的设备树文件*//*此内容是内核编译和文件系统编译的部分,在此不做分析,在内核移植的章节会分析*/
export LINUXKERNEL_INSTALL_DIR=$SDK_PATH/linux-imx
echo LINUXKERNEL_INSTALL_DIR:$LINUXKERNEL_INSTALL_DIR
export LINUX_DEFCONFIG=defconfig
echo LINUX_DEFCONFIG:$LINUX_DEFCONFIGif [ $BOARD_TYPE == "DDR4" ]; thenexport LINUX_DTB=itop8mm-evk.dtb
elseexport LINUX_DTB=fsl-imx8mm-evk.dtb
fi
echo LINUX_DTB:$LINUX_DTBexport INSTALL_MOD_STRIP=1
echo INSTALL_MOD_STRIP:$INSTALL_MOD_STRIPexport DESTDIR_UBUNTU20DESK=$SDK_PATH/ubuntu20desk
echo DESTDIR_UBUNTU20DESK:$DESTDIR_UBUNTU20DESKexport DESTDIR_UBUNTU20CORE=$SDK_PATH/ubuntu20core
echo DESTDIR_UBUNTU20CORE:$DESTDIR_UBUNTU20COREexport DESTDIR_DEBIAN=$SDK_PATH/debian
echo DESTDIR_DEBIAN:$DESTDIR_DEBIANexport DESTDIR_YOCTO=$SDK_PATH/yocto
echo DESTDIR_YOCTO:$DESTDIR_YOCTOexport DESTDIR_YOCTO=$SDK_PATH/buildroot
echo DESTDIR_BUILDROOT:$DESTDIR_BUILDROOTexport DESTDIR=$SDK_PATH/rootfs
echo DESTDIR:$DESTDIR
/*end */export IMX_MKimage=$SDK_PATH/imx-mkimage /* 制作镜像 IMX_MKimage的目录*/
echo IMX_MKimage:$IMX_MKimage/*打印IMX_MKimage */
export IMX_PLATFORM=$IMX_MKimage/iMX8M /*设置IMX_PLATFORM为iMX8M*/
echo IMX_PLATFORM:$IMX_PLATFORM /*打印IMX_PLATFORM */build_type=$1
export RESULT_OUT=result
#rm -rf $RESULT_OUT
#mkdir $RESULT_OUTfunction clean_uboot_image()
{echo =================================echo clean uboot imageecho =================================/*清除uboot镜像*/
rm -rf $IMX_PLATFORM/$UBOOT_DTBrm -rf $IMX_PLATFORM/u-boot*rm -rf $IMX_PLATFORM/flash.binrm -rf $IMX_PLATFORM/bl31.bin
}/*编译atf*/
function build_atf()
{echo =================================echo build imx_atf imageecho =================================make -C $ATF_INSTALL_DIR distcleanmake -C $ATF_INSTALL_DIR PLAT=imx8mm LDFLAGS=""/*编译完之后,将生成的镜像拷贝到IMX_PLATFORM:iMX8M目录下*/cp $ATF_INSTALL_DIR/build/imx8mm/release/bl31.bin $IMX_PLATFORM
}
/*编译uboot*/
function build_uboot()
{#build ubootecho =================================echo build imx_ubootecho =================================#make -C $UBOOT_INSTALL_DIR distcleanmake -j $MAKE_JOBS -C $UBOOT_INSTALL_DIR $UBOOT_DEFCONFIGmake -j $MAKE_JOBS -C $UBOOT_INSTALL_DIR/*编译完之后将编译好的文件拷贝到IMX_PLATFORM:iMX8M目录下*/#create ubootcp $UBOOT_INSTALL_DIR/u-boot-nodtb.bin $IMX_PLATFORMcp $UBOOT_INSTALL_DIR/spl/u-boot-spl.bin $IMX_PLATFORMcp $UBOOT_INSTALL_DIR/arch/arm/dts/$UBOOT_DTB $IMX_PLATFORM/*生成uboot镜像*/#generate uboot imageecho =================================echo generate imx_uboot imageecho =================================if [ $BOARD_TYPE == "DDR4" ]; thenmake -C $IMX_MKimage SOC=iMX8MM flash_ddr4_evkelsemake -C $IMX_MKimage SOC=iMX8MM flash_spl_ubootfi#make -C $IMX_MKimage SOC=iMX8MM flash_ddr4_evk/*将生成的flash.bin拷贝到result目录下*/cp $IMX_PLATFORM/flash.bin $RESULT_OUT/
}/*编译内核的函数*/
#build linux kernel
function build_kernel()
{echo =================================echo build linux kernelecho =================================make -j $MAKE_JOBS -C $LINUXKERNEL_INSTALL_DIR $LINUX_DEFCONFIG LDFLAGS=""make -j $MAKE_JOBS -C $LINUXKERNEL_INSTALL_DIR LDFLAGS=""rm -rf $RESULT_OUT/boot.imgmkfs.vfat -n "Boot imx8mmevk" -S 512 -C $RESULT_OUT/boot.img 65536mcopy -i $RESULT_OUT/boot.img -s $LINUXKERNEL_INSTALL_DIR/arch/arm64/boot/Image ::/Imagemcopy -i $RESULT_OUT/boot.img -s $LINUXKERNEL_INSTALL_DIR/arch/arm64/boot/dts/freescale/$LINUX_DTB ::/$LINUX_DTBmcopy -i $RESULT_OUT/boot.img -s $LINUXKERNEL_INSTALL_DIR/arch/arm64/boot/dts/freescale/$LINUX_ITOP8MM_7_0_DTB ::/$LINUX_ITOP8MM_7_0_DTBmcopy -i $RESULT_OUT/boot.img -s $LINUXKERNEL_INSTALL_DIR/arch/arm64/boot/dts/freescale/$LINUX_ITOP8MM_9_7_DTB ::/$LINUX_ITOP8MM_9_7_DTBmcopy -i $RESULT_OUT/boot.img -s $LINUXKERNEL_INSTALL_DIR/arch/arm64/boot/dts/freescale/$LINUX_ITOP8MM_10_1_DTB ::/$LINUX_ITOP8MM_10_1_DTBmcopy -i $RESULT_OUT/boot.img -s $LINUXKERNEL_INSTALL_DIR/arch/arm64/boot/dts/freescale/$LINUX_ITOP8MM_MIPI_DTB ::/$LINUX_ITOP8MM_MIPI_DTB#build linux moduleecho =================================echo build linux moduleecho =================================if [ "$build_type" = "ubuntu20desk" ]thenmake -C $LINUXKERNEL_INSTALL_DIR LDFLAGS="" INSTALL_MOD_PATH=$DESTDIR_UBUNTU20DESK INSTALL_MOD_STRIP=$INSTALL_MOD_STRIP modules_install#exit 1elif [ "$build_type" = "ubuntu20core" ]thenmake -C $LINUXKERNEL_INSTALL_DIR LDFLAGS="" INSTALL_MOD_PATH=$DESTDIR_UBUNTU20CORE INSTALL_MOD_STRIP=$INSTALL_MOD_STRIP modules_install#exit 1elif [ "$build_type" = "debian" ]thenmake -C $LINUXKERNEL_INSTALL_DIR LDFLAGS="" INSTALL_MOD_PATH=$DESTDIR_DEBIAN INSTALL_MOD_STRIP=$INSTALL_MOD_STRIP modules_install#exit 1elif [ "$build_type" = "yocto" ]thenmake -C $LINUXKERNEL_INSTALL_DIR LDFLAGS="" INSTALL_MOD_PATH=$DESTDIR_YOCTO INSTALL_MOD_STRIP=$INSTALL_MOD_STRIP modules_install#exit 1elif [ "$build_type" = "buildroot" ]thenmake -C $LINUXKERNEL_INSTALL_DIR LDFLAGS="" INSTALL_MOD_PATH=$DESTDIR_BUILDROOT INSTALL_MOD_STRIP=$INSTALL_MOD_STRIP modules_install#exit 1elif [ "$build_type" = "rootfs" ]thenmake -C $LINUXKERNEL_INSTALL_DIR LDFLAGS="" INSTALL_MOD_PATH=$DESTDIR INSTALL_MOD_STRIP=$INSTALL_MOD_STRIP modules_install#exit 1elseecho =================================echo please input parameterecho =================================fi
}
/*编译文件系统的函数*/
#generate rootfs.sdcard
function generate_rootfs()
{set -erawsize=8192fatsize=65536#ext4size=3145728#ext4size=1845728ext4size=2145728totalsize=`expr $rawsize + $fatsize + $ext4size + $rawsize`dd if=/dev/zero of=$RESULT_OUT/rootfs.ext4 bs=1K count=0 seek=$ext4sizeecho "totalbytes:$totalsize"#chown -h -R 0:0 $DESTDIR$SDK_PATH/bin/mkfs.ext4 -F -i 4096 $RESULT_OUT/rootfs.ext4 -d $DESTDIR$SDK_PATH/bin/fsck.ext4 -pvfD $RESULT_OUT//rootfs.ext4fatstart=$rawsizefatend=`expr $rawsize + $fatsize`ext4start=$fatendext4end=`expr $fatend + $ext4size`echo $ext4enddd if=/dev/zero of=$RESULT_OUT/rootfs.sdcard bs=1K count=0 seek=$totalsizeparted -s $RESULT_OUT/rootfs.sdcard mklabel msdosparted -s $RESULT_OUT/rootfs.sdcard unit KiB mkpart primary fat32 $fatstart $fatendparted -s $RESULT_OUT/rootfs.sdcard unit KiB mkpart primary $ext4start $ext4endparted $RESULT_OUT/rootfs.sdcard printdd if=$RESULT_OUT/flash.bin of=$RESULT_OUT/rootfs.sdcard conv=notrunc seek=33 bs=1Kecho $fatstartbytesecho $ext4startbytesdd if=$RESULT_OUT/boot.img of=$RESULT_OUT/rootfs.sdcard conv=notrunc,fsync seek=1K bs=$fatstartdd if=$RESULT_OUT/rootfs.ext4 of=$RESULT_OUT/rootfs.sdcard conv=notrunc,fsync seek=1K bs=$ext4start
}/*编译Ubuntu20desk的函数*/
# build ubuntu20desk
function generate_ubuntu20desk_rootfs()
{echo =================================echo start build ubuntu20deskecho =================================set -erawsize=8192fatsize=65536#ext4size=3145728#ext4size=1845728ext4size=6145728totalsize=`expr $rawsize + $fatsize + $ext4size + $rawsize`dd if=/dev/zero of=$RESULT_OUT/rootfs.ext4 bs=1K count=0 seek=$ext4sizeecho $totalbytes#chown -h -R 0:0 $DESTDIR_UBUNTU20DESK$SDK_PATH/bin/mkfs.ext4 -F -i 4096 $RESULT_OUT/rootfs.ext4 -d $DESTDIR_UBUNTU20DESK$SDK_PATH/bin/fsck.ext4 -pvfD $RESULT_OUT//rootfs.ext4fatstart=$rawsizefatend=`expr $rawsize + $fatsize`ext4start=$fatendext4end=`expr $fatend + $ext4size`echo $ext4enddd if=/dev/zero of=$RESULT_OUT/rootfs.sdcard bs=1K count=0 seek=$totalsizeparted -s $RESULT_OUT/rootfs.sdcard mklabel msdosparted -s $RESULT_OUT/rootfs.sdcard unit KiB mkpart primary fat32 $fatstart $fatendparted -s $RESULT_OUT/rootfs.sdcard unit KiB mkpart primary $ext4start $ext4endparted $RESULT_OUT/rootfs.sdcard printdd if=$RESULT_OUT/flash.bin of=$RESULT_OUT/rootfs.sdcard conv=notrunc seek=33 bs=1Kecho $fatstartbytesecho $ext4startbytesdd if=$RESULT_OUT/boot.img of=$RESULT_OUT/rootfs.sdcard conv=notrunc,fsync seek=1K bs=$fatstartdd if=$RESULT_OUT/rootfs.ext4 of=$RESULT_OUT/rootfs.sdcard conv=notrunc,fsync seek=1K bs=$ext4start
}
/*编译Ubuntu20core的函数*/
# build ubuntu20core
function generate_ubuntu20core_rootfs()
{echo =================================echo start build ubuntu20coreecho =================================set -erawsize=8192fatsize=65536#ext4size=3145728#ext4size=1845728ext4size=6145728totalsize=`expr $rawsize + $fatsize + $ext4size + $rawsize`dd if=/dev/zero of=$RESULT_OUT/rootfs.ext4 bs=1K count=0 seek=$ext4sizeecho $totalbyteschown -h -R 0:0 $DESTDIR_UBUNTU20CORE$SDK_PATH/bin/mkfs.ext4 -F -i 4096 $RESULT_OUT/rootfs.ext4 -d $DESTDIR_UBUNTU20CORE$SDK_PATH/bin/fsck.ext4 -pvfD $RESULT_OUT//rootfs.ext4fatstart=$rawsizefatend=`expr $rawsize + $fatsize`ext4start=$fatendext4end=`expr $fatend + $ext4size`echo $ext4enddd if=/dev/zero of=$RESULT_OUT/rootfs.sdcard bs=1K count=0 seek=$totalsizeparted -s $RESULT_OUT/rootfs.sdcard mklabel msdosparted -s $RESULT_OUT/rootfs.sdcard unit KiB mkpart primary fat32 $fatstart $fatendparted -s $RESULT_OUT/rootfs.sdcard unit KiB mkpart primary $ext4start $ext4endparted $RESULT_OUT/rootfs.sdcard printdd if=$RESULT_OUT/flash.bin of=$RESULT_OUT/rootfs.sdcard conv=notrunc seek=33 bs=1Kecho $fatstartbytesecho $ext4startbytesdd if=$RESULT_OUT/boot.img of=$RESULT_OUT/rootfs.sdcard conv=notrunc,fsync seek=1K bs=$fatstartdd if=$RESULT_OUT/rootfs.ext4 of=$RESULT_OUT/rootfs.sdcard conv=notrunc,fsync seek=1K bs=$ext4start
}/*编译Debian的函数*/
# build debian
function generate_debian_rootfs()
{echo =================================echo start build debianecho =================================set -erawsize=8192fatsize=65536#ext4size=3145728#ext4size=1845728ext4size=6145728totalsize=`expr $rawsize + $fatsize + $ext4size + $rawsize`dd if=/dev/zero of=$RESULT_OUT/rootfs.ext4 bs=1K count=0 seek=$ext4sizeecho $totalbytes#chown -h -R 0:0 $DESTDIR_DEBIAN$SDK_PATH/bin/mkfs.ext4 -F -i 4096 $RESULT_OUT/rootfs.ext4 -d $DESTDIR_DEBIAN$SDK_PATH/bin/fsck.ext4 -pvfD $RESULT_OUT//rootfs.ext4fatstart=$rawsizefatend=`expr $rawsize + $fatsize`ext4start=$fatendext4end=`expr $fatend + $ext4size`echo $ext4enddd if=/dev/zero of=$RESULT_OUT/rootfs.sdcard bs=1K count=0 seek=$totalsizeparted -s $RESULT_OUT/rootfs.sdcard mklabel msdosparted -s $RESULT_OUT/rootfs.sdcard unit KiB mkpart primary fat32 $fatstart $fatendparted -s $RESULT_OUT/rootfs.sdcard unit KiB mkpart primary $ext4start $ext4endparted $RESULT_OUT/rootfs.sdcard printdd if=$RESULT_OUT/flash.bin of=$RESULT_OUT/rootfs.sdcard conv=notrunc seek=33 bs=1Kecho $fatstartbytesecho $ext4startbytesdd if=$RESULT_OUT/boot.img of=$RESULT_OUT/rootfs.sdcard conv=notrunc,fsync seek=1K bs=$fatstartdd if=$RESULT_OUT/rootfs.ext4 of=$RESULT_OUT/rootfs.sdcard conv=notrunc,fsync seek=1K bs=$ext4start
}
/*编译yocto的函数*/
# build yocto
function generate_yocto_rootfs()
{echo =================================echo start build yoctoecho =================================set -erawsize=8192fatsize=65536#ext4size=6145728#ext4size=3145728#ext4size=1845728ext4size=2145728#ext4size=1505728totalsize=`expr $rawsize + $fatsize + $ext4size + $rawsize`dd if=/dev/zero of=$RESULT_OUT/rootfs.ext4 bs=1K count=0 seek=$ext4sizeecho $totalbytes#chown -h -R 0:0 $DESTDIR_YOCTO$SDK_PATH/bin/mkfs.ext4 -F -i 4096 $RESULT_OUT/rootfs.ext4 -d $DESTDIR_YOCTO$SDK_PATH/bin/fsck.ext4 -pvfD $RESULT_OUT//rootfs.ext4fatstart=$rawsizefatend=`expr $rawsize + $fatsize`ext4start=$fatendext4end=`expr $fatend + $ext4size`echo $ext4enddd if=/dev/zero of=$RESULT_OUT/rootfs.sdcard bs=1K count=0 seek=$totalsizeparted -s $RESULT_OUT/rootfs.sdcard mklabel msdosparted -s $RESULT_OUT/rootfs.sdcard unit KiB mkpart primary fat32 $fatstart $fatendparted -s $RESULT_OUT/rootfs.sdcard unit KiB mkpart primary $ext4start $ext4endparted $RESULT_OUT/rootfs.sdcard printdd if=$RESULT_OUT/flash.bin of=$RESULT_OUT/rootfs.sdcard conv=notrunc seek=33 bs=1Kecho $fatstartbytesecho $ext4startbytesdd if=$RESULT_OUT/boot.img of=$RESULT_OUT/rootfs.sdcard conv=notrunc,fsync seek=1K bs=$fatstartdd if=$RESULT_OUT/rootfs.ext4 of=$RESULT_OUT/rootfs.sdcard conv=notrunc,fsync seek=1K bs=$ext4start
}/*编译buildroot的函数*/
# build buildroot
function generate_buildroot_rootfs()
{echo =================================echo start build buildrootecho =================================set -erawsize=8192fatsize=65536#ext4size=6145728ext4size=3145728#ext4size=1845728#ext4size=2145728#ext4size=1505728totalsize=`expr $rawsize + $fatsize + $ext4size + $rawsize`dd if=/dev/zero of=$RESULT_OUT/rootfs.ext4 bs=1K count=0 seek=$ext4sizeecho $totalbytes#chown -h -R 0:0 $DESTDIR_YOCTO$SDK_PATH/bin/mkfs.ext4 -F -i 4096 $RESULT_OUT/rootfs.ext4 -d $DESTDIR_YOCTO$SDK_PATH/bin/fsck.ext4 -pvfD $RESULT_OUT//rootfs.ext4fatstart=$rawsizefatend=`expr $rawsize + $fatsize`ext4start=$fatendext4end=`expr $fatend + $ext4size`echo $ext4enddd if=/dev/zero of=$RESULT_OUT/rootfs.sdcard bs=1K count=0 seek=$totalsizeparted -s $RESULT_OUT/rootfs.sdcard mklabel msdosparted -s $RESULT_OUT/rootfs.sdcard unit KiB mkpart primary fat32 $fatstart $fatendparted -s $RESULT_OUT/rootfs.sdcard unit KiB mkpart primary $ext4start $ext4endparted $RESULT_OUT/rootfs.sdcard printdd if=$RESULT_OUT/flash.bin of=$RESULT_OUT/rootfs.sdcard conv=notrunc seek=33 bs=1Kecho $fatstartbytesecho $ext4startbytesdd if=$RESULT_OUT/boot.img of=$RESULT_OUT/rootfs.sdcard conv=notrunc,fsync seek=1K bs=$fatstartdd if=$RESULT_OUT/rootfs.ext4 of=$RESULT_OUT/rootfs.sdcard conv=notrunc,fsync seek=1K bs=$ext4start
}/*根据传入不同的参数进行不同的操作*/
if [ "$1" = "clean" ] //如果参数是clean,则清除编译
thenecho =================================echo clean allecho =================================make -C $ATF_INSTALL_DIR distcleanmake -C $UBOOT_INSTALL_DIR distcleanmake -C $LINUXKERNEL_INSTALL_DIR distcleanclean_uboot_imageexit 1
elif [ "$1" = "atf" ] //如果参数是atf,则编译atf
thenbuild_atf#exit 1
elif [ "$1" = "uboot" ] //如果参数是uboot,则编译uboot
thenbuild_uboot#exit 1
elif [ "$1" = "kernel" ] //如果参数是kernel,则编译kernel
thenbuild_kernel#exit 1elif [ "$1" = "ubuntu20desk" ] //如果参数是ubuntu20desk,则编译ubuntu20deskthenbuild_atfbuild_ubootbuild_kernelgenerate_ubuntu20desk_rootfs#exit 1elif [ "$1" = "ubuntu20core" ]//如果参数是ubuntu20core,则编译ubuntu20core
thenbuild_atfbuild_ubootbuild_kernelgenerate_ubuntu20core_rootfs#exit 1elif [ "$1" = "debian" ]//如果参数是debian,则编译debian
thenbuild_atfbuild_ubootbuild_kernelgenerate_debian_rootfs#exit 1elif [ "$1" = "yocto" ]//如果参数是yocto,则编译yocto
thenbuild_atfbuild_ubootbuild_kernelgenerate_yocto_rootfs#exit 1
elif [ "$1" = "rootfs" ]
thenbuild_atfbuild_ubootbuild_kernelgenerate_rootfs#exit 1
elif [ "$1" = "buildroot" ]
thenbuild_atfbuild_ubootbuild_kernelgenerate_buildroot_rootfs#exit 1
elseecho =================================echo please input parameterecho =================================#exit 1
fi
69.2 增加bin文件
将网盘资料里面“iTOP-i.MX8MM开发板\02-i.MX8MM开发板网盘资料汇总(不含光盘内容)\嵌入式Linux开发指南(iTOP-i.MX8MM)手册配套资料\3.Linux系统移植\5.移植uboot需要用的文件”提供的文件拷贝到/home/topeet/bsp_kernel_imx目录下。
69.3 配置电源管理芯片
迅为iMX8MM采用了PCA9450A电源管理,拒绝老旧方案,采用NXP全新研制配套i.MX8M Mini的电源管理芯片,有六个降压稳压器,五个线性稳压器和一个负载开关,为整个系统的稳定运行提供了更可靠的保证。接下来我们需要在uboot源码中配置好电源管理芯片。
1 首先在默认的uboot设备树中进行配置,打开/home/topeet/bsp_kernel_imx/bsp_kernel_imx/uboot-imx/arch/arm/dts/fsl-imx8mm-evk.dts文件,将默认的电源管理芯片注释掉,替换为pca9450。修改为如下图所示:
#endif
#if 0pmic: bd71837@4b {reg = <0x4b>;compatible = "rohm,bd71837";/* PMIC BD71837 PMIC_nINT GPIO1_IO3 */pinctrl-0 = <&pinctrl_pmic>;gpio_intr = <&gpio1 3 GPIO_ACTIVE_LOW>;gpo {rohm,drv = <0x0C>; /* 0b0000_1100 all gpos with cmos output mode */};regulators {#address-cells = <1>;#size-cells = <0>;bd71837,pmic-buck2-uses-i2c-dvs;bd71837,pmic-buck2-dvs-voltage = <1000000>, <900000>, <0>; /* VDD_ARM: Run-Idle */buck1_reg: regulator@0 {reg = <0>;regulator-compatible = "buck1";regulator-min-microvolt = <700000>;regulator-max-microvolt = <1300000>;regulator-boot-on;regulator-always-on;regulator-ramp-delay = <1250>;};buck2_reg: regulator@1 {reg = <1>;regulator-compatible = "buck2";regulator-min-microvolt = <700000>;regulator-max-microvolt = <1300000>;regulator-boot-on;regulator-always-on;regulator-ramp-delay = <1250>;};buck3_reg: regulator@2 {reg = <2>;regulator-compatible = "buck3";regulator-min-microvolt = <700000>;regulator-max-microvolt = <1300000>;};buck4_reg: regulator@3 {reg = <3>;regulator-compatible = "buck4";regulator-min-microvolt = <700000>;regulator-max-microvolt = <1300000>;};buck5_reg: regulator@4 {reg = <4>;regulator-compatible = "buck5";regulator-min-microvolt = <700000>;regulator-max-microvolt = <1350000>;regulator-boot-on;regulator-always-on;};buck6_reg: regulator@5 {reg = <5>;regulator-compatible = "buck6";regulator-min-microvolt = <3000000>;regulator-max-microvolt = <3300000>;regulator-boot-on;regulator-always-on;};buck7_reg: regulator@6 {reg = <6>;regulator-compatible = "buck7";regulator-min-microvolt = <1605000>;regulator-max-microvolt = <1995000>;regulator-boot-on;regulator-always-on;};buck8_reg: regulator@7 {reg = <7>;regulator-compatible = "buck8";regulator-min-microvolt = <800000>;regulator-max-microvolt = <1400000>;regulator-boot-on;regulator-always-on;};ldo1_reg: regulator@8 {reg = <8>;regulator-compatible = "ldo1";regulator-min-microvolt = <3000000>;regulator-max-microvolt = <3300000>;regulator-boot-on;regulator-always-on;};ldo2_reg: regulator@9 {reg = <9>;regulator-compatible = "ldo2";regulator-min-microvolt = <900000>;regulator-max-microvolt = <900000>;regulator-boot-on;regulator-always-on;};ldo3_reg: regulator@10 {reg = <10>;regulator-compatible = "ldo3";regulator-min-microvolt = <1800000>;regulator-max-microvolt = <3300000>;regulator-boot-on;regulator-always-on;};ldo4_reg: regulator@11 {reg = <11>;regulator-compatible = "ldo4";regulator-min-microvolt = <900000>;regulator-max-microvolt = <1800000>;regulator-boot-on;regulator-always-on;};ldo5_reg: regulator@12 {reg = <12>;regulator-compatible = "ldo5";regulator-min-microvolt = <1800000>;regulator-max-microvolt = <3300000>;};ldo6_reg: regulator@13 {reg = <13>;regulator-compatible = "ldo6";regulator-min-microvolt = <900000>;regulator-max-microvolt = <1800000>;regulator-boot-on;regulator-always-on;};ldo7_reg: regulator@14 {reg = <14>;regulator-compatible = "ldo7";regulator-min-microvolt = <1800000>;regulator-max-microvolt = <3300000>;};};};
#elsepmic: pca9450@25 {reg = <0x25>;compatible = "nxp,pca9450";/* PMIC PCA9450 PMIC_nINT GPIO1_IO3 */pinctrl-0 = <&pinctrl_pmic>;gpio_intr = <&gpio1 3 GPIO_ACTIVE_LOW>;gpo {nxp,drv = <0x0C>; /* 0b0000_1100 all gpos with cmos output mode */};regulators {#address-cells = <1>;#size-cells = <0>;pca9450,pmic-buck2-uses-i2c-dvs;pca9450,pmic-buck2-dvs-voltage = <1000000>, <900000>, <0>; /* VDD_ARM: Run-Idle */buck1_reg: regulator@0 {reg = <0>;regulator-compatible = "buck1";regulator-min-microvolt = <600000>;regulator-max-microvolt = <2187500>;regulator-boot-on;regulator-always-on;regulator-ramp-delay = <3125>;};buck2_reg: regulator@1 {reg = <1>;regulator-compatible = "buck2";regulator-min-microvolt = <600000>;regulator-max-microvolt = <2187500>;regulator-boot-on;regulator-always-on;regulator-ramp-delay = <3125>;};buck3_reg: regulator@2 {reg = <2>;regulator-compatible = "buck3";regulator-min-microvolt = <600000>;regulator-max-microvolt = <2187500>;regulator-boot-on;regulator-always-on;};buck4_reg: regulator@3 {reg = <3>;regulator-compatible = "buck4";regulator-min-microvolt = <600000>;regulator-max-microvolt = <3400000>;regulator-boot-on;regulator-always-on;};buck5_reg: regulator@4 {reg = <4>;regulator-compatible = "buck5";regulator-min-microvolt = <600000>;regulator-max-microvolt = <3400000>;regulator-boot-on;regulator-always-on;};buck6_reg: regulator@5 {reg = <5>;regulator-compatible = "buck6";regulator-min-microvolt = <600000>;regulator-max-microvolt = <3400000>;regulator-boot-on;regulator-always-on;};ldo1_reg: regulator@6 {reg = <6>;regulator-compatible = "ldo1";regulator-min-microvolt = <1600000>;regulator-max-microvolt = <3300000>;regulator-boot-on;regulator-always-on;};ldo2_reg: regulator@7 {reg = <7>;regulator-compatible = "ldo2";regulator-min-microvolt = <800000>;regulator-max-microvolt = <1150000>;regulator-boot-on;regulator-always-on;};ldo3_reg: regulator@8 {reg = <8>;regulator-compatible = "ldo3";regulator-min-microvolt = <800000>;regulator-max-microvolt = <3300000>;regulator-boot-on;regulator-always-on;};ldo4_reg: regulator@9 {reg = <9>;regulator-compatible = "ldo4";regulator-min-microvolt = <800000>;regulator-max-microvolt = <3300000>;regulator-boot-on;regulator-always-on;};ldo5_reg: regulator@10 {reg = <10>;regulator-compatible = "ldo5";regulator-min-microvolt = <1800000>;regulator-max-microvolt = <3300000>;};};};
2 然后修改pmic的驱动uboot-imx/drivers/power/pmic/Kconfig,添加如下图所示代码:
config DM_PMIC_PCA9450bool "Enable Driver Model for PMIC PCA9450"depends on DM_PMIChelpThis config enables implementation of driver-model pmic uclass featuresfor PMIC PCA9450. The driver implements read/write operations.
3 然后修改uboot-imx/drivers/power/pmic/Makefile文件,添加如下图所示代码:
obj-$(CONFIG_$(SPL_)DM_PMIC_PCA9450) += pca9450.o
obj-$(CONFIG_POWER_PCA9450) += pmic_pca9450.o
4 然后将资料包里面的pca9450.c和pmic_pca9450.c拷贝到源码uboot-imx/drivers/power/pmic/目录下。
5 修改uboot-imx/include/configs/imx8mm_evk.h文件,修改为如下图所示:
#if 0
#define CONFIG_POWER_BD71837
#else
#define CONFIG_POWER_PCA9450
#endif
#ifdef CONFIG_TARGET_IMX8MM_DDR4_EVK
#define CONFIG_SYS_FSL_USDHC_NUM 2//1
#else
#define CONFIG_SYS_FSL_USDHC_NUM 2
#endif
接下来重新打开一个窗口,输入make menuconfig,我们在menuconfig中配置PCA9450,如下图所示:
然后点击保存“save”到configs/imx8mm_ddr4_evk_defconfig,如下图所示:
然后输入以下命令,将默认的配置文件覆盖.config文件。
make imx8mm_ddr4_evk_defconfig
69.4 配置otg烧写
打开设备树文件uboot-imx/arch/arm/dts/fsl-imx8mm-evk.dts,修改节点为如下图所示:
&usbotg1 {
status = "okay";
/*extcon = <&typec_ptn5110_1>;*/
drm_mode= "otg";
picophy,pre-emp-curr-control = <3>;
picophy,dc-vol-level-adjust = <7>;
};
&usbotg2 {
status = "okay";
/*extcon = <&typec_ptn5110_2>;*/
drm_mode= "otg";
picophy,pre-emp-curr-control = <3>;
picophy,dc-vol-level-adjust = <7>;
};
修改uboot-imx/arch/arm/dts/fsl-imx8mm-evk.dts文件,修改为如下图所示:
static ulong bootloader_mmc_offset(void)
{if (is_imx8m() || (is_imx8() && is_soc_rev(CHIP_REV_A)))return 0x8400;else if (is_imx8qm()) {int dev_no = mmc_get_env_dev();if (MEK_8QM_EMMC == dev_no)/* target device is eMMC boot0 partition, bootloader offset is 0x0 */return 0x0;else/* target device is SD card, bootloader offset is 0x8000 */return 0x8000;}else if (is_imx8())return 0x8000;elsereturn 0x400;
}
修改uboot-imx/drivers/usb/gadget/f_fastboot.c,修改为如下图所示:
static int _fastboot_setup_dev(int *switched)
{char *fastboot_env;struct fastboot_device_info devinfo;;fastboot_env = env_get("fastboot_dev");if (fastboot_env) {if (!strcmp(fastboot_env, "sata")) {devinfo.type = DEV_SATA;devinfo.dev_id = 0;
#if defined(CONFIG_FASTBOOT_STORAGE_MMC)} else if (!strncmp(fastboot_env, "mmc", 3)) {devinfo.type = DEV_MMC;devinfo.dev_id = mmc_get_env_dev();
#endif} else {return 1;}} else {return 1;}
#ifdef CONFIG_FLASH_MCUFIRMWARE_SUPPORT/* For imx7ulp, flash m4 images directly to spi nor-flash, M4 will* run automatically after powered on. For imx8mq, flash m4 images to* physical partition 'm4_os', m4 will be kicked off by A core. */fastboot_firmwareinfo.type = ANDROID_MCU_FRIMWARE_DEV_TYPE;
#endifif (switched) {if (devinfo.type != fastboot_devinfo.type || devinfo.dev_id != fastboot_devinfo.dev_id)*switched = 1;else*switched = 0;}fastboot_devinfo.type = devinfo.type;fastboot_devinfo.dev_id = devinfo.dev_id;return 0;
}
69.5 修改默认的配置文件
源码默认的配置文件是uboot-imx/configs/imx8mm_ddr4_evk_defconfig,我们修改此文件,我们将DEFAULT_FDT_FILE修改为itop8mm-evk.dtb,如下图所示:DEFAULT_FDT_FILE是设置内核默认的设备树文件。
CONFIG_DEFAULT_FDT_FILE="itop8mm-evk.dtb"
将这行注释掉,如下图所示:
#CONFIG_USB_TCPC=y
69.6 修改i2c.h
修改uboot-imx/arch/arm/include/asm/arch-imx8/i2c.h文件,添加如下图所示代码:
#include <asm/arch/lpcg.h>
static struct imx_i2c_map imx_i2c_desc[] = {
{0, SC_R_I2C_0},
{1, SC_R_I2C_1},
{2, SC_R_I2C_2},
{3, SC_R_I2C_3},
{4, SC_R_I2C_4},
{5, SC_R_LVDS_0_I2C_0}, /* lvds0 i2c0 */
{6, SC_R_LVDS_0_I2C_0}, /* lvds0 i2c1 */
{7, SC_R_LVDS_1_I2C_0}, /* lvds1 i2c0 */
{8, SC_R_LVDS_1_I2C_0}, /* lvds1 i2c1 */
{9, SC_R_CSI_0_I2C_0},
{10, SC_R_CSI_1_I2C_0},
{11, SC_R_HDMI_I2C_0},
{12, SC_R_HDMI_RX_I2C_0},
{13, SC_R_MIPI_0_I2C_0},
{14, SC_R_MIPI_0_I2C_1},
{15, SC_R_MIPI_1_I2C_0},
{16, SC_R_MIPI_1_I2C_1},
};
69.7 测试烧写
修改完上述功能,然后输入以下命令编译uboot,如下图所示:
clear && ./build.sh uboot
编译完会在result目录下生成flash.bin文件,如下图所示:
然后我们可以烧写生成的flash.bin +网盘默认提供的rootfs.sdcard镜像,如果uboot可以正常启动内核镜像,说明uboot移植成功。Uboot启动如下图所示:
接下来的章节我们来学习移植内核。