第12讲 Linux内核启动流程简介
一、vmlinux.lds简介
从arch/arm/kernel/vmlinux.lds分析Linux内核第一行启动代码。找到
ENTRY(stext)
入口函数是stext,image和zImage是经过压缩的,Linux内核会先进行解压缩,解压缩完成以后就要运行Linux内核。要求:
1、MMU关闭
2、D cache关闭
3、I cache无所谓
4、r0 = 0。
5、r1 = machine nr
6、r2=atags 或设备树
二、Linux入口stext
__vet_atags 函数验证atags或dtb是否有效,如果使用设备树的话就是dtb。
__create_page_tables 创建页表。
ldr r13, =mmap_switched 也就是r13保存mmap_switched。
__enable_mmu 使能MMU
-> __turn_mmu_on
->_mmap_switched
->start_kernel 启动内核。
Linux内核第一阶段。
三、__mmap_switched函数
四、start_kernel函数
Linux内核第二阶段
start_kernel
-> rest_init
-> kernel_thread(kernel_init, NULL, CLONE_FS); 创建kernel_init进程。也就是
init进程,PID=1
-> kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES); 创建kthreadd
进程,进程PID为2。
-> cpu_startup_entry 进入空闲进程,也就是主进程退化为空闲进程,idle。
启动开发板,输入:ps -A,列出当前系统所有进程。
五、reset_init函数
六、init进程
kernel_init
-> kernel_init_freeable
-> 设置标准输入、标准输出、标准错误使用console,比如ttymxc0
-> ramdisk_execute_command = "/init";
-> 检查/init是否存在,存在的话就运行。
-> uboot传递给Linux内核的bootargs可以自定init=xxx,或者叫命令行参数。
有一些开发板会设置init=linuxrc。
-> 试着运行/sbin/init。
-> /etc/init
-> /bin/init
-> /bin/sh
可以看出,最终引出根文件系统。
第13讲 Linux内核移植
一、创建VSCode工程
1、将NXP官方的linux内核拷贝到Ubuntu。
2、解压缩tar -vxjf linux-imx-rel_imx_4.1.15_2.1.0_ga.tar.bz2
二、NXP官方开发板Linux内核编译
编译NXP官方EVK开发板对应的Linux系统,默认配置文件存放路径arch/arm/configs。最终编译出:zImage,和 imx6ull-14x14-evk-emmc.dtb,imx6ull-14x14-evk.dtb。
将zImage,和 imx6ull-14x14-evk-emmc.dtb拷贝到tftpboot目录下,然后在uboot中通过tftp服务启动。
经过测试,发现NXP官方开发板对应的zImage和.dtb可以在正点原子开发板上启动。
Linux启动遇到上述错误,那是因为没有跟文件系统。
三、使能8线EMMC
修改设备树,imx6ull-alientek-emmc.dts。节点usdhc2。
四、网络驱动修改
为何要一开始就修改网络驱动??在做Linux驱动开发的时候一般都是通过网络调试的。
修改网络复位IO和PHY ID以后,Linux内核内部通用PHY驱动已经正常工作。
LAN8720的生产厂家是SMSC。使能SMSC驱动,然后重新编译Linux内核,并启动,tftp启动。
三、在Linux中添加自己的开发板
2、一个就是imx6_alientek_emmc_defconfig默认配置文件。
3、imx6ull-alientek-emmc.dts编译出来就是.dtb文件。
复制arch/arm/configs/imx_v7_mfg_defconfig文件为imx_alientek_emmc_defconfig。
复制arch/arm/boot/dts/imx6ull-14x14-evk.dts文件为imx6ull-alientek-emmc.dts
修改arch/arm/boot/dts/Makefile,
四、CPU主频和网络驱动修改
1、修改驱动之前,要先保证板子能够正常启动。
2、根文件系统处理好,使用现成根文件系统。保证EMMC烧写了系统,设置bootcmd和bootargs。
Bootcmd设置默认从网络启动,通过TFTP。
Setenv bootcmd ‘tftp 80800000 zImage;tftp 83000000 imx6ull-alientek-emmc.dtb;bootz 80800000 - 83000000;’
Bootargs设置,根文件系统存放在EMMC的分区2里面,命令如下:
Setenv bootargs ‘console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw’
现在的问题就是EMMC驱动有问题,在imx6ull-alientek-emmc.dts中找到usdhc2节点。将usdhc2改为:
&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";
};
完了以后编译设备树。使用如下命令:
Make dtbs。
1、配置主频
超频到696MHz,NXP官方宣传为700MHz。打开imx6ull.dtsi文件