文章目录
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,115200root=/dev/mmcblk1p2rootwaitrw
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中
文件涵义如下:
Performance,最高性能,直接用最高频率,不考虑耗电Interactive,一开始直接用最高频率,之后按照CPU负载渐渐减少Powersave,节电模式,一般以最低频率运行,系统性能会受影响,通常不会用这个Userspace,可以在用户空间自动调节频度Ondemand,定时检测负载,之后依照负载来调节频度。负载低的时侯减少CPU频度
复印当前频度:792M
CPU可支持的切换频度有4种:
我们更改工作频度,在配置文件上将默认工作模式改为Powersave模式
sudo vim arch/arm/configs/imx_my_emmc_defconfig
添加默认代码
更改后重新编译,从网路启动系统内核,之后查看系统运行频度,弄成198M了
更改工作频度的技巧不仅更改defconfig文件,还可以通过图形化配置,使用
make menuconfig
图形化配置后再生成配置文件,之后编译,两种方式结果都一样
通常使用ondemand模式,一可节电,二可降低发热
不仅以上的工作频度,我们也可以运行自己想要的程序,具体更改就不多说了,通常使用原厂提供的就行
4.2EMMC驱动更改
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换为了LAN87208720A,Linux内核自带的网路驱动未能驱动,须要做更改
4.3.1更改芯片复位引脚
打开设备树文件imx6ull-my-emmc.dts找到下边的代码,删掉多余IO口配置
更改后:
删掉如下代码,让GPIO5_IO07和GPIO5_IO08分别作为ENET1和ENET2的复位引脚
之后找到iomuxc_snvs,将刚才删掉的两个引脚作为复位引脚配置,代码如下:
4.3.2网路时钟引脚配置
在imx6ull-my-emmc.dtslinux驱动移植,将如下两个代码
前面的参数更改为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中加入如下代码:
用于复位两个芯片,保证正常工作node.js安装linux,输入下边代码,打开图形化界面
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常用命令,添加软复位
在Linux中须要对LAN87208720A进行一次软复位,保证正常工作,LAN87208720A的驱动文件是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保存更改后配置文件
更改网路驱动的时侯我们通过图形界面使能了LAN87208720A的驱动,使能后会在.config中存在如下代码
CONFIG_SMSC_PHY=y
当CONFIG_SMSC_PHY=y的时侯才会编译smsc.c这个驱动文件linux驱动移植,当我们执行makeclean清除工程之后.config文件才会被删掉掉,所以要保存该文件
非图形化下,将生成的.config文件直接更名imx_my_emmc_defconfig配置文件,保存到arch/arm/configs下
在图形化界面将生成的.config文件更名imx_my_emmc_defconfig配置文件,保存到arch/arm/configs下
五、移植总结