linux系统移植:原厂kernel移植到开发板(代码片段)

嵌入式up笔记 嵌入式up笔记     2022-12-02     486

关键词:

文章目录

Linux系统移植:原厂 Kernel 移植到开发板

一、获取原厂内核并编译

我直接拿原子提供的源码编译,编译指令

#!/bin/sh
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- imx_v7_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- all -j16

编译完获得镜像文件:

设备树文件:

二、内核启动测试

从板子上通过网络来启动编译好的 linux 内核,看看现象,要想网络互相 ping 通,必须要在局域网下!

设置板子 uboot 的 bootargs 参数为 console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw

setenv bootargs console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw

然后将生成的镜像文件和设备树拷贝到 FTP 根目录,用于从网络启动:

cp arch/arm/boot/dts/imx6ull-14x14-evk.dtb ~/linux/tftp/
cp arch/arm/boot/zImage ~/linux/tftp/

在开发板输入

tftp 80800000 zImage
tftp 83000000 imx6ull-14x14-evk.dtb
bootz 80800000 - 83000000

进行网络启动,系统启动成功,可以输入命令:

我们刚刚启动的根文件系统由 uboot 的 bootargs 环境变量进行指引,其中 root=/dev/mmcblk1p2 就是指引了根文件系统的参数存放在EMMC 的分区 2 中,没有跟文件系统的话就会启动不成功,根文件系统缺失会导致的内核崩溃

三、添加自己板子文件

添加针对正点原子阿尔法开发板的配置文件

3.1 板子配置文件

将 arch/arm/configs 下的 imx_v7_mfg_defconfig 配置文件复制一份, 命名为我们自己配置文件的名称imx_my_emmc_defconfig,以后就在里面修改配置我们自己的内核

cp arch/arm/configs/imx_v7_mfg_defconfig arch/arm/configs/imx_my_emmc_defconfig

然后就可以使用

make imx_my_emmc_defconfig

配置 Linux 内核了

3.2 板子设备树

从目录 arch/arm/boot/dts 中复制一份 imx6ull-14x14-evk.dts,重命名为 imx6ull-my-emmc.dts 作为我们自己板子的设备树,以后就在里面修改

cp arch/arm/boot/dts/imx6ull-14x14-evk.dts arch/arm/boot/dts/imx6ull-my-emmc.dts

然后在 arch/arm/boot/dts/Makefile,找到 “dtb-$(CONFIG_SOC_IMX6ULL)” 配置项,在此配置项中加入 “imx6ull-my-emmc.dtb” 将我们的设备树追加进去,dts 编译会生成 dtb

3.3 编译

修改之前的编译脚本

#!/bin/sh
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- imx_my_emmc_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- all -j16

赋予脚本执行权限,然后执行,编译完成入如下,编译成功上面内核配置没问题

复制 zImage 和设备树 .dtb 文件到 tftp 目录下,使用网络启动,加载我们自己的设备树:

tftp 80800000 zImage
tftp 83000000 imx6ull-my-emmc.dtb
bootz 80800000 - 83000000

启动成功:

四、重要配置修改

4.1 主频修改

在启动系统上打印 CPU 主频,运行频率信息存放在 /sys/bus/cpu/devices/cpu0/cpufreq 中

文件含义如下:

  • cpuinfo_cur_freq:当前 cpu 工作频率,从 CPU 寄存器读取到的工作频率
  • cpuinfo_max_freq:处理器所能运行的最高工作频率(单位: KHz)
  • cpuinfo_min_freq :处理器所能运行的最低工作频率(单位: KHz)
  • cpuinfo_transition_latency:处理器切换频率所需要的时间(单位:ns)
  • scaling_available_frequencies:处理器支持的主频率列表(单位: KHz)
  • scaling_available_governors:当前内核中支持的所有 governor(调频)类型
  • scaling_cur_freq:保存着 cpufreq 模块缓存的当前 CPU 频率,不会对 CPU 硬件寄存器进行检查
  • scaling_driver:该文件保存当前 CPU 所使用的调频驱动
  • scaling_governor:governor(调频)策略,Linux 内核一共有 5 中调频策略
  1. Performance,最高性能,直接用最高频率,不考虑耗电
  2. Interactive,一开始直接用最高频率,然后根据 CPU 负载慢慢降低
  3. Powersave,省电模式,通常以最低频率运行,系统性能会受影响,一般不会用这个
  4. Userspace,可以在用户空间手动调节频率
  5. Ondemand,定时检查负载,然后根据负载来调节频率。负载低的时候降低 CPU 频率
  • scaling_max_freq:governor(调频)可以调节的最高频率
  • cpuinfo_min_freq:governor(调频)可以调节的最低频率

打印当前频率:792M

CPU 可支持的切换频率有 4 种:

我们修改工作频率,在配置文件中将默认工作模式改为 Powersave 模式

sudo vim arch/arm/configs/imx_my_emmc_defconfig

添加默认代码

修改后重新编译,从网络启动系统内核,然后查看系统运行频率,变成 198M 了

修改工作频率的方法除了修改 defconfig 文件,还可以通过图形化配置,使用

make menuconfig

图形化配置后再生成配置文件,然后编译,两种方法结果都一样

一般使用 ondemand 模式,一可省电,二可减少发热

除了以上的工作频率,我们也可以运行自己想要的程序,具体修改就不多说了,一般使用原厂提供的就行

4.2 EMMC驱动修改

Linux 内核驱动里面 EMMC 默认是 4 线模式的,没有 8 线模式的速度快,所以我们将 EMMC 的驱动修改为 8 线

修改 EMMC 接线直接修改设备树就行,打开文件 imx6ull-alientek-emmc.dts,将下面的配置文件

修改为

然后单独编译 dts 到 dtb:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- dtbs

重新启动系统

4.3 网络驱动修改

原子开发板的网络和 NXP 官方的网络硬件上不同,网络 PHY 芯片由 KSZ8081 换为了 LAN8720A,Linux 内核自带的网络驱动无法驱动,需要做修改

4.3.1 修改芯片复位引脚

打开设备树文件 imx6ull-my-emmc.dts 找到下面的代码,删除多余 IO 口配置

修改后:

删除如下代码, 让 GPIO5_IO07 和 GPIO5_IO08 分别作为 ENET1 和 ENET2 的复位引脚

然后找到 iomuxc_snvs,将刚刚删除的两个引脚作为复位引脚配置,代码如下:

4.3.2 网络时钟引脚配置

在 imx6ull-my-emmc.dts ,将如下两个代码

后面的参数修改为 0x4001b009(两个引脚的电气属性值)

4.3.3 修改节点的 pinctrl-0 属性

修改位置如下

将这两个节点属性修改为下图,传入我们上面写的复位函数:

4.3.4 修改网口节点以及添加复位

设备树文件中,在 fec2 的节点有写网口的地址信息

修改 reg 的值,对应 0 和 1,因为 ethernet-phy@ 后面的数字是 PHY 的地址,而 ENET1 的 PHY 地址为 0,
所以 @ 后面是 0,ENET2 同理:

在两个 fec 节点内添加复位引脚,并设置持续时间 200ms,用于后面的软件复位使用

在节点中添加驱动信息,指引内核找到对应的驱动程序

配置完成后,重新编译设备树

4.3.5 修改网络驱动

打 开 drivers/net/ethernet/freescale/fec_main.c 文件,在函数 fec_probe 中加入如下代码:

用于复位两个芯片,保证正常工作,输入下面代码,打开图形化界面

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-  menuconfig

在界面使能网口驱动,路径如下

-> Device Drivers
    -> Network device support
        -> PHY Device support and infrastructure
        	-> Drivers for SMSC PHYs

勾选后就会编译 LAN8720 驱动

4.3.6 修改 smsc.c 文件,添加软复位

在 Linux 中需要对 LAN8720A 进行一次软复位,保证正常工作,LAN8720A 的驱动文件是drivers/net/phy/smsc.c,修改该文件即可,找到里面的 smsc_phy_reset 复位函数

修改为下面的代码

	//初始化变量
	int err, phy_reset;
	int msec = 1;
	struct device_node *np;
	int timeout = 50000;
	//获取 FEC1 网卡对应的设备节点
	if(phydev->addr == 0) /* FEC1 */ 
	
		np = of_find_node_by_path("/soc/aips-bus@02100000/ethernet@02188000");
		if(np == NULL)
		
			return -EINVAL;
		
	
	//获取 FEC2 网卡对应的设备节点
	if(phydev->addr == 1) /* FEC2 */ 
	
		np = of_find_node_by_path("/soc/aips-bus@02000000/ethernet@020b4000");
		if(np == NULL)
		
			return -EINVAL;
		
	
	//从设备树中获取“phy-reset-duration”属性信息,也就是复位时间
	err = of_property_read_u32(np, "phy-reset-duration", &msec);
	/* A sane reset duration should not be longer than 1s */
	if (!err && msec > 1000)
		msec = 1;
	//从设备树中获取“phy-reset-gpios”属性信息,也就是复位 IO
	phy_reset = of_get_named_gpio(np, "phy-reset-gpios", 0);
	if (!gpio_is_valid(phy_reset))
		return;
	//复位 LAN8720A
	gpio_direction_output(phy_reset, 0);
	gpio_set_value(phy_reset, 0);
	msleep(msec);
	gpio_set_value(phy_reset, 1);
	//处于 Powerdown 模式的时候才会软复位 LAN8720
	int rc = phy_read(phydev, MII_LAN83C185_SPECIAL_MODES);
	if (rc < 0)
		return rc;
	if ((rc & MII_LAN83C185_MODE_MASK) ==MII_LAN83C185_MODE_POWERDOWN) 
	
		/* set "all capable" mode and reset the phy */
		rc |= MII_LAN83C185_MODE_ALL;
		phy_write(phydev, MII_LAN83C185_SPECIAL_MODES, rc);
	
	phy_write(phydev, MII_BMCR, BMCR_RESET);
	/* wait end of reset (max 500 ms) */
	do 
		udelay(10);
		if (timeout-- == 0)
		return -1;
		rc = phy_read(phydev, MII_BMCR);
	 while (rc & BMCR_RESET);
	return 0;

修改好设备树和 Linux 内核以后重新编译一下,启动 Linux 内核,使用 ifconfig 命令查看网卡

ping 一下主机,成功

4.4 保存修改后配置文件

修改网络驱动的时候我们通过图形界面使能了 LAN8720A 的驱动,使能后会在.config 中存在如下代码

CONFIG_SMSC_PHY=y

当 CONFIG_SMSC_PHY=y 的时候就会编译 smsc.c 这个驱动文件,当我们执行 make clean 清理工程以后.config 文件就会被删除掉,所以要保存该文件

  • 非图形化

非图形化下,将生成的 .config 文件直接改名 imx_my_emmc_defconfig 配置文件,保存到 arch/arm/configs下

  • 图形化

在图形化界面将生成的 .config 文件改名 imx_my_emmc_defconfig 配置文件,保存到 arch/arm/configs 下

五、移植总结

  • 搞到原厂kernel源码
  • 复制配置文件、设备树文件,编译下载测试一下linux能不能启动
  • 修改配置文件
  • 修改设备树文件(网口、EMMC、串口等重要的设备树和驱动文件,适配自己的板子)
  • 编译生成针对开发板的的 zImage 和设备树文件
  • 移植 rootfs
  • 完结撒花

rk3399系统移植|基于rk-linux-sdk移植kernel(4.4.194)(代码片段)

一、使用已有配置测试1.编译配置查看已有配置:编译配置:exportARCH=arm64exportCROSS_COMPILE=aarch64-linux-gnu-makerockchip_linux_defconfig2.编译make-j83.测试使用rk3399-evb开发板的设备树生成img镜像:makerk3399-evb-ind-lpddr4-linux.img 查看详情

rk3399系统移植|基于rk-linux-sdk移植kernel(4.4.194)(代码片段)

一、使用已有配置测试1.编译配置查看已有配置:编译配置:exportARCH=arm64exportCROSS_COMPILE=aarch64-linux-gnu-makerockchip_linux_defconfig2.编译make-j83.测试使用rk3399-evb开发板的设备树生成img镜像:makerk3399-evb-ind-lpddr4-linux.img 查看详情

正点原子i.mx6u-mini移植篇kernel移植过程详解(代码片段)

...、下载Linux内核这里使用NXP官方提供的Linux源码,将其移植到正点原子I.MX6U-MINI开发板上。NXP官方原版Liux源码路径为:1、例程源码->4、NXP官方原版Uboot和Linux->linux-imx-rel_imx4.1.15_2.1.0_ga.tar.bz2。在ubunut中的/home/zhiguoxin/linu... 查看详情

stm32mp157系统移植|移植st官方5.10内核到小熊派开发板(代码片段)

Linux内核移植流程移植Linux内核到一个新的板子上时,需要以下步骤:(1)选择一个硬件设计接近的板子,基于此板相关文件开始移植(2)拷贝单板配置文件(arch/arm/configs)(3)拷贝设... 查看详情

stm32mp157系统移植|移植st官方5.10内核到小熊派开发板(代码片段)

Linux内核移植流程移植Linux内核到一个新的板子上时,需要以下步骤:(1)选择一个硬件设计接近的板子,基于此板相关文件开始移植(2)拷贝单板配置文件(arch/arm/configs)(3)拷贝设... 查看详情

怎样移植u-boot和linux到s3c2440开发板

...启动。本文就介绍如何实现该功能,并组成一个最简单的系统,这不仅要移植uboot,还要移植linux内核及创建一个根文件系统。首先我们对nandflash进行分区,规划好每个文件存放在nandflash的位置。下面是nandflash的分区:第0分区:0... 查看详情

1.学习大纲

...ARM体系结构、ARM汇编、开发板常见外设裸机编程);Linux系统移植(uboot移植、kernel移植、rootfs制作);Linux驱动开发;第二部分:AndroidAndroidHAL驱动;Android系统定制;Android应用开发;第三部分:IotGPS和地图查询服务;Wifi;蓝牙4.0;Z... 查看详情

linux|移植nxp官方linux内核到imx6ull开发板(4.1.15)(代码片段)

一、NXP官方linux内核1.下载NXP官方linux仓库地址为:https://github.com/Freescale/linux-fslc。这里为了保持版本统一,使用正点原子资料包中提供的原厂linux:linux-imx-rel_imx_4.1.15_2.1.0_ga.tar.bz2(版本是4.1.15)。2.编译安装 查看详情

mplayer移植到am335x开发板

参考《mplayer移植到arm心得》 ,http://blog.csdn.net/xiaohuangzhilin/article/details/52399746移植了mplayer1.0rc2版本 ./configure--prefix=/usr/local/mplayer--cc=arm-linux-gnueabihf-gcc--target=arm-linux--dis 查看详情

正点原子i.mx6u-mini移植篇kernel移植过程详解(代码片段)

...eInsight工程这里我们使用NXP官方提供的Linux源码,将其移植到正点原子I.MX6U-ALPHA开发板上。NXP官方原版Liux源码已经放到了开发板光盘中,路径为:1、例程源码->4、NXP官方原版Uboot和Linux->linux-imx-relimx4.1.15_2.1.0_ga.tar.... 查看详情

嵌入式linux高级案例-移植lvgl到linux开发板(代码片段)

1.概述​本篇主要是记录将LVGL移植到百问网STM32MP157开发板上,并且仅是跑一下LVGL的一些例程。2.软件平台​本次使用的是Ubuntu18.04,是由百问网提供的,并且是按照他们的手册搭建好了交叉编译环境,花了一点时... 查看详情

嵌入式linux应用初步移植mqtt到ubuntu和linux开发板(代码片段)

1.概述​本篇主要是记录将MQTT移植安装到百问网STM32MP157开发板上,并且是跑一下MQTT的一个例程来验证,要完成本次移植安装,必须要保证电脑和开发板都能上网。。2.软件平台​本次使用的是Ubuntu18.04,是由百问... 查看详情

linux系统移植:kernel顶层makefile(下)(代码片段)

文章目录Linux系统移植:Kernel顶层Makefile(下)一、makedefconfig过程二、Makefile.build脚本分析三、make过程四、built-in.o文件编译生成过程五、makezImage过程Linux系统移植:Kernel顶层Makefile(下)继续分析Linux内核... 查看详情

成功移植sqlite3到armlinux开发板

...te,是一款轻型的数据库,是遵守ACID的关联式数据库管理系统,它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持Windows/... 查看详情

i.mx6ull应用移植|移植tslib到linux开发板(1.22)(代码片段)

一、tslib二、移植到imx6ull开发板1.下载源码tslib的github仓库为:https://github.com/libts/tslib。下载最新发布的tag,为1.22版本:2.移植(1)解压源码:xz-dtslib-1.22.tar.xztar-xftslib-1.22.tar解压后的文件如图&#x 查看详情

linux系统移植:kernel顶层makefile(上)(代码片段)

文章目录Linux系统移植:Kernel顶层Makefile(上)一、版本号二、MAKEFLAGS变量三、命令输出四、静默输出五、编译结果输出目录六、代码检查七、模块编译八、设置目标架构和交叉编译器九、调用构建文件十、交叉编译... 查看详情

基于v3s的语音助手移植pyaudio到开发板(代码片段)

基于V3S的语音助手(二)移植pyaudio到开发板1.前期准备portaudio源码pyaudio源码2.交叉编译portaudio配置./configureCC=arm-linux-gnueabihf-gccCXX=CC=arm-linux-gnueabihf-g++--host=arm-linux-gnueabihf 查看详情

linux系统移植:nxp官板uboot移植(代码片段)

文章目录Linux系统移植:NXP官板uboot移植一、获取官板U-Boot二、编译下载U-Boot源码三、官方驱动验证Linux系统移植:NXP官板uboot移植移植NXP的IMX6ULL官板U-Boot到原子的开发板一、获取官板U-Boot去NXP官网下载评估板的U-Boot,... 查看详情