linux kernel 移植终极总结

1.linux 内核包含七大子系统

1、内存管理子系统   负责 寻找空闲的虚拟地址 和 物理地址进行映射 一旦系统启动 程序都是面想虚拟地址编程 。寄存器地址指针 操作物理地址的方式将不复存在。

如果没有操作系统,内存是需要程序自己来管理的。譬如在uboot中要使用内存的哪里是自己随便用的,没有注册也没有限制。这时候如果程序自己不小心把同一块内存重复用了就会出现程序逻辑错误。系统大了之后(内存多了)内存管理非常麻烦;有了操作系统之后,操作系统负责管控所有的内存,所有的应用程序需要使用内存时都要向操作系统去申请和注册,由操作系统的内存管理模块来分配内存给你使用,这样好处是可以保证内存使用不会冲突

2、进程管理子系统  负责 多进程多任务处理 提高 CPU的处理能力 ,宏观上的并行就是操作系统提供的分时复用机制,提高 CPU的使用率 和  即时处理能力,完成 每个进程的。

调度 管理,销毁,PCB资源记录。 进程就是人 PCB就是户口本,对每个人进行管理。

操作系统下支持多个应用程序同时运行(所以可以一边聊QQ一边看电影···),这是宏观上的并行。实际上在单核心CPU上微观上是不能并行的,宏观上的并行就是操作系统提供的分时复用机制。操作系统的进程调度模块负责在各个进程之间进行切换。

3、设备管理系统  负责 和 每个硬件 设备进行 通过通信交互的 接口 ,它将以 文件 的方式 ,被用户程序进行访问。

没有操作系统时要控制任何硬件都要自己写代码,有了操作系统后操作系统本身会去控制各个硬件,应用程序就不用考虑硬件的具体细节了。操作系统的硬件设备管理模块就是驱动模块。

4、网络管理系统  负责  网络协议栈 网络设备的 管理,通过它能和 其他计算机 设备进行 通信。牛不牛逼。

5、文件管理系统  将系统里的一切静态存放的东西 抽象成目录 和 文件的方式 可以被用户直观的进行 交互。

文件系统是管理存储设备的一种方式。存储设备是由很多个扇区组成的,每个扇区有512/1024/2048/4096字节,存储设备要以扇区为单位进行读写。如果没有文件系统,程序要自己去读写扇区,就得记得哪个文件在哪个扇区。有了文件系统之后我们人不用再关注扇区,人只用关注文件系统中的目录和文件名,而不用管这个文件在物理磁盘的哪个扇区。

6、系统调用  提供 用户层与 linux 内核  交互的接口,也是和系统交互的唯一方式,没有之一。

7、平台相关  支持芯片架构相关 多种不同的硬件架构。

2、linux 内核编译流程

2.1 修改源码目录
mv linux-imx-rel_imx_4.1.15_2.1.0_ga linux-imx-test

2.2 修改顶层 Makefile 里面的 ARCHCROSS_COMPILE 

ARCH=arm

CROSS_COMPILE=arm-linux-gnueabihf-

2.3 make clean 

清理一下linux 内核之前的文件

2.4 配置 Linux 内核

make imx_v7_mfg_defconfig
2.5 编译内核 
make -j4
2.6 编译输出文件 
①、 arch/arm/boot/ zImage
②、 arch/arm/boot/dts imx6ull-alientek-emmc.dtb
3.  移植到目标板
3.1 添加开发板默认配置文件 
cd arch/arm/configs
cp imx_v7_mfg_defconfig imx_alientek_emmc_defconfig
3.2 配置目标板的配置文件
make imx_alientek_emmc_defconfig
3.3 添加设备树
cd arch/arm/boot/dts
cp imx6ull-14x14-evk.dts imx6ull-alientek-emmc.dts
3.4 vim Makefile 
imx6ull - 14x14 - evk - usb - certi . dtb \  后面添加下面这行
imx6ull-alientek-emmc.dtb \
3.5 制作编译脚本  imx6ull_alientek_emmc.sh
#!/bin/sh
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihfimx_alientek_emmc_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- all -j16
chmod 777 imx6ull_alientek_emmc.sh
// 给予可执行权限
./imx6ull_alientek_emmc.sh
// 执行 shell 脚本编译内核
3.6  调整主频策略 
cd arch/arm/boot/dts  vim imx_alientek_emmc_defconfig
屏蔽 41 CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND = y
在 44  CONFIG_CPU_FREQ_GOV_INTERACTIVE = y
后面添加 CONFIG_CPU_FREQ_GOV_ONDEMAND = y
验证:cat  /sys/devices/system/cpu/cpu0/cpufreq/ cpuinfo_cur_freq 文件 792000
图形化文档进行配置 
3.7 修改  EMMC 驱动  EMMC 是 8线驱动 但是  linux 内核默认的是  4线模式 
直接修改设备树
usdhc2 改为   make dtbs 重新编译一下设备树 
&usdhc2 {           
        pinctrl-names = "default", "state_100mhz", "state_200mhz";
        pinctrl-0 = <&pinctrl_usdhc2_8bit>;
        pinctrl-1 = <&pinctrl_usdhc2_8bit_100mhz>;
        pinctrl-2 = <&pinctrl_usdhc2_8bit_200mhz>;
        bus-width = <8>;
        non-removable;
        status = "okay";
};
3.8 修改网络驱动   imx6ull-alientek-emmc.dts
网络 PHY 芯片由 KSZ8081 换为了 LAN8720A ,两个网络 PHY 芯片的复位 IO 也不同。
所以 Linux 内核自带的网络驱动是驱动不起来 I.MX6U-ALPHA 开发板上的网络的。
ENET1 复位引脚 ENET1_RST 连接在 I.M6ULL 的 SNVS_TAMPER7 这个引脚上。
ENET2 的复位引脚 ENET2_RST 连接在 I.MX6ULL 的 SNVS_TAMPER8 上。
584 pinctrl_spi4 : spi4grp {  中
删除 
MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07 0x70a1
MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08 0x80000000
125 spi4 {
129 pinctrl - assert - gpios = <& gpio5 8 GPIO_ACTIVE_LOW >;
133 cs - gpios = <& gpio5 7 0 >;
129 行,设置 GPIO5_IO08 SPI4 的一个功能引脚 ( 我也不清楚具体作为什么功能用 )
GPIO5_IO08 就是 SNVS_TAMPER8 GPIO 功能引脚。
133 行,设置 GPIO5_IO07 作为 SPI4 的片选引脚,而 GPIO5_IO07 就是 SNVS_TAMPER7
GPIO 功能引脚。
1 & iomuxc_snvs {
                pinctrl_enet1_reset: enet1resetgrp { 
                        fsl,pins = < 
                                MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07 0x10B0
                        >; 
                };      
                pinctrl_enet2_reset: enet2resetgrp {
                        fsl,pins = < 
                                MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08 0x10B0
                        >;
                };
增加配置菱角
309 pinctrl_enet1 : enet1grp {
317 MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01
0x1b0b0
318 MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 0x4001b009
322 pinctrl_enet2 : enet2grp {
332 MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01
0x1b0b0
333 MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 0x4001b009
& fec1 {
pinctrl - names = "default" ;
pinctrl-0 = <&pinctrl_enet1
&pinctrl_enet1_reset>;
pinctrl-0 = <&pinctrl_enet2
&pinctrl_enet2_reset>;
171 & fec1 {
172 pinctrl - names = "default" ;
173 pinctrl - 0 = <& pinctrl_enet1
174 & pinctrl_enet1_reset >;
175 phy - mode = "rmii" ;
176 phy - handle = <& ethphy0 >;
177 phy-reset-gpios = <&gpio5 7 GPIO_ACTIVE_LOW>;
178 phy-reset-duration = <200>;
179 status = "okay" ;
180 };
182 & fec2 {
183 pinctrl - names = "default" ;
184 pinctrl - 0 = <& pinctrl_enet2
185 & pinctrl_enet2_reset >;
186 phy - mode = "rmii" ;
187 phy - handle = <& ethphy1 >;
188 phy-reset-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>;
189 phy-reset-duration = <200>;
190 status = "okay" ;
196 ethphy0 : ethernet - phy@ 0 {
197 compatible = "ethernet-phy-ieee802.3-c22" ;
198 smsc,disable-energy-detect;
199 reg = < 0 >;
200 };
202 ethphy1 : ethernet - phy@1 {
203 compatible = "ethernet-phy-ieee802.3-c22" ;
204 smsc,disable-energy-detect;
205 reg = < 1 >;
206 };
修改  drivers/net/ethernet/freescale/fec_main.c
函数 fec_probe
void __iomem *IMX6U_ENET1_TX_CLK;
void __iomem *IMX6U_ENET2_TX_CLK;
IMX6U_ENET1_TX_CLK = ioremap(0X020E00DC, 4);
writel(0X14, IMX6U_ENET1_TX_CLK);
IMX6U_ENET2_TX_CLK = ioremap(0X020E00FC, 4);
writel(0X14, IMX6U_ENET2_TX_CLK);
LAN8720A 的驱动文件是 drivers/net/phy/smsc.c
#include <linux/of_gpio.h>
#include <linux/io.h>
smsc_phy_reset 函数

        int err, phy_reset;
        int msec = 1;
        struct device_node *np;
        int timeout = 50000;
        if(phydev->addr == 0) /* FEC1 */ {
                np = of_find_node_by_path("/soc/aips-bus@02100000/ethernet@02188000");
                if(np == NULL) {
                        return -EINVAL;
                }
        }

        if(phydev->addr == 1) /* FEC2 */ {
                np = of_find_node_by_path("/soc/aips-bus@02000000/ethernet@020b4000");
                if(np == NULL) {
                return -EINVAL;
                }
        }

        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 = of_get_named_gpio(np, "phy-reset-gpios", 0);
        if  (!gpio_is_valid(phy_reset))
                return;
        gpio_direction_output(phy_reset, 0);
        gpio_set_value(phy_reset, 0);
        msleep(msec);
        gpio_set_value(phy_reset, 1);

输入命令“ make menuconfig ”,打开图形化配置界面
选择使能 LAN8720A 的驱动
-> Device Drivers
-> Network device support
-> PHY Device support and infrastructure
-> Drivers for SMSC PHYs
勾选这个以后就会编译 LAN8720 驱动
3.9 网络驱动测试:
修改好设备树和 Linux 内核以后重新编译一下,得到新的 zImage 镜像文件和 imx6ull
alientek-emmc.dtb 设备树文件
查看网卡设备
ifconfig -a 
打开网卡 
ifconfig eth0 up
ifconfig eth1 up
SMSC LAN8710/LAN8720   当前的 网络驱动使用的 就是我们前面使能的 SMSC 驱动
ping 一下能ping成功说明 网络驱动修改成功。
保存修改后的图形化配置文件
.config  CONFIG_SMSC_PHY=y
drivers/net/phy/Makefile
obj - $ ( CONFIG_SMSC_PHY ) += smsc . o
直接将 .config 文件另 存为 imx_alientek_emmc_defconfig
imx_alientek_emmc_defconfig

3.linux 系统移植终极总结

①、在 Linux 内核中查找可以参考的板子,一般都是半导体厂商自己做的开发板。
②、编译出参考板子对应的 zImage 和.dtb 文件。
③、使用参考板子的 zImage 文件和.dtb 文件在我们所使用的板子上启动 Linux 内核,看能
否启动。
④、如果能启动的话就万事大吉,如果不能启动那就悲剧了,需要调试 Linux 内核。不过
一般都会参考半导体官方的开发板设计自己的硬件,所以大部分情况下都会启动起来。启动
Linux 内核用到的外设不多,一般就 DRAM(Uboot 都初始化好的)和串口。作为终端使用的串口
一般都会参考半导体厂商的 Demo 板。
⑤、修改相应的驱动,像 NAND Flash、EMMC、SD 卡等驱动官方的 Linux 内核都是已经
提供好了,基本不会出问题。重点是网络驱动,因为 Linux 驱动开发一般都要通过网络调试代
码,所以一定要确保网络驱动工作正常。如果是处理器内部 MAC+外部 PHY 这种网络方案的
话,一般网络驱动都很好处理,因为在 Linux 内核中是有外部 PHY 通用驱动的。只要设置好复
位引脚、PHY 地址信息基本上都可以驱动起来。
⑥、Linux 内核启动以后需要根文件系统,如果没有根文件系统的话肯定会崩溃,所以确定 Linux
内核移植成功以后就要开始根文件系统的构建。
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦幽风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值