Linux_kernel移植linux09

一、温故知新

        1、分析uboot源码目录

        每个目录基本上都会有自己的Makefile进行当前层级目录的编译,最后在整个uboot源码目录中会有一个Makefile文件进行整合,将每一层级编译出的目标文件,整合到一起,链接到一起,最终生成ubootpak.bin

        2、启动过程

                uboot启动时,执行第一条代码 b reset

                设置SVC管理模式、关闭看门狗、禁止L1与L2缓存以及关闭MMU、 判断CPU-ID是否合法、清空bss段、打开MMU、跳转到board_init_f对硬件进行初始化、跳转到board_init_r指定堆栈区域并初始化EMMC、跳转到main_loop、cli_loop、cli_simple_loop

                board_init_f完成一系列硬件的初始化

                        8大硬件(CPU、定时器、看门狗、串口、USB、网卡、EMMC、中断)

                board_init_r完成存储类的初始化,解析uboot命令行的内容

                        bootcmd、bootargs

        3、修改uboot默认的环境变量

                【1】uboot倒计时

                【2】本地ip地址

                【3】服务端ip地址

                【4】bootcmd

                【5】bootargs

                【6】uboot终端提示符

        4、修改启动logo

二、移植Linux内核

        1、查看linux内核版本

                uname -a

        2、linux内核的源码目录结构

1)arch体系结构

与uboot中的arch类似

包含了与特定硬件架构相关的代码,如:x86 \ ARM等

2)block块块设备的IO操作
3)crypto加密加密的API
4)Documentation文档内核中各部分的文档
5)drivers设备设备驱动程序
6)firmware固件用于存储固件的目录
7)fs文件系统用于存储文件系统
8)include头文件内核提供的API头文件
9)init初始化内核启动的初始化代码
a)ipc进程通信进程间通信的代码
b)kernel内核内核的核心代码,包括:进程调用 \ 时钟等
c)lib库包含了内核用到的库
d)mm内存管理

存放内存管理的代码

linux内核的5大功能

1】进程间通信

2】进程管理

3】网络子系统

4】虚拟文件子系统

5】内存管理

e)net有关网络网络相关的代码
f)scripts脚本配置内核所用的脚本
g)security安全安全模块
h)sound声音音频相关的驱动和模块
i)tools工具构建内核时需要使用的工具
j)usr用户提供了用户空间的内核空间的接口
k)virt虚拟虚拟化的支持

         3、编译Linux内核

                1)修改Makefile文件

                vim kernel/Makefile

                /*在开头添加以下内容*/

                ARCH ?= arm

                CROSS_COMPILE ?= arm-cortex_a9-linux-gnueabi-

                2)拷贝文件

                /*将arm架构下的默认配置文件拷贝到kernel目录*/

                cp arch/arm/configs/x6818_deconfig .config

                /*将uboot源码中的mkimage工具拷贝到根目录下的bin目录*/

                sudo cp uboot/tools/mkimage /bin

                3)编译内核

                make uImage -j4

注释:

        -j4:指定make同时运行的任务数,4核并发操作

                4)将编译好的uImage拷贝到tftp共享目录中

                cp arch/arm/boot/uImage /tftpboot/

                5)修改环境变量在emmc中的存储位置

                vim uboot/include/configs/x6818.h

原因:咱们之前添加一个logo,大小为900*1024,防止存储位置产生重叠,我们将环境变量的位置进行了后移。由于uboot大小的变化,我们需要重新对EMMC进行分区。

                6)对EMMC重新分区

                【1】擦除emmc

                mmc erase 0 100000

                【2】重新分区

                fdisk 2 3 0x400000:0x4000000 0x4400000:0x2f200000 0x33600000:0

                【3】重新移植uboot

                这次给它分了4Mb的空间

                7)下位机操作

                tftp 0x48000000 uImage

                mmc write 48000000 2000 3000

                setenv bootcmd mmc read 0x48000000 2000 3000\; bootm 48000000

                setenv bootargs root=/dev/nfs

                                           nfsroot=192.168.1.8:/nfs_share/rootfs

                                           ip=192.168.1.6:192.168.1.8:192.168.1.1:255.255.255.0

                                           init=/linuxrc console=ttySAC0,115200 maxcpus=1 lcd=wy070ml

                                          tp=gslx680-linux loglevel=2

                saveenv

注释:

        bootcmd:告诉uboot去哪个地方加载内核

        bootargs:告诉linux内核去哪个地方挂载根文件系统,以什么方式挂载

        loglevel=2:将log日志设置为2级

三、Linux内核的配置

        1、配置Linux的原因

                1)linux支持多种架构

                linux支持arm、x86。。。架构,可以将我们需要的硬件平台的代码与通用代码一起参与编译,最终生成我们需要的硬件平台的代码uImage

                2)linux内核集成了大量的功能

                当我们具体到某一款嵌入式产品时,可能只需要其中一部分的功能,如:路由器,我们不需要显示屏,也不需要触摸屏,所以我们可以将内核中有关这两部分的代码进行裁减,Linux内核允许通过配置方式将程序员选中的功能编译进内核,用来选择哪些功能参与编译,哪些功能不参与编译,这个过程就是内核的裁减

        2、使用menuconfig工具

                make menuconfig

--------------------------------------------

“↑”、“↓”:进行菜单的选择

"←"、"→":进行功能的选择(<Select>、<Exit>、<Help>)

回车:进入所选内容进行配置

空格:选中该项内容 / 取消该项内容

--------------------------------------------

        3、其他配置linux的方法

                【1】make menuconfig        // 图形化界面配置linux内核

                【2】make config                // 纯文字终端界面

                【3】make xconfig              // 需要QT4的支持

                【4】make gconfig              // 需要GTK的支持

                注意:通过make menuconfig修改的Linux内核配置会影响.config的文件内容

四、Linux的编译

        1、进行裁减的逻辑

        make menuconfig配置完成之后,会影响.config文件

        在make uImage时,Makefile文件会按照.config文件中的配置进行编译,并影响到内核的生成

        2、编译后的生成文件

        内核编译之后会生成三个文件:uImage、zImage、Image

        uImage:uboot专用的映像文件

        zImage:内核的映像压缩文件

        Image:内核映像文件

区别:uImage-zImage

uImage是在zImage之前加上了一个长度为64字节的“头”,记录了在这个内核的版本 \ 加载的位置 \ 生成的时间 \ 大小,在64字节之后的内容与zImage没有区别

        3、vimlinux、vimlinuz、vimlinux.bin

vimlinux:是Linux内核编译后未经任何压缩或处理的原始二进制映像,不可以引导的内核

vimlinuz:是vimlinux经过gzip压缩的linux内核映像文件,可以引导的内核

vimlinux.bin:Linux原始影像的二进制文件

五、Linux内核的启动流程 

        1、查找入口点文件

        rm vmlinux                // 使内核重新编译

        make V=1 > 1.txt        //将编译和链接的详细过程都显示出来并重定向到1.txt文件中

        grep "vmlinux" 1.txt        //筛选包含"vimlinux"关键字的行,打印到终端

        arch/arm/kernel/head.o        // 编译后的内核入口文件,原文件应该是head.S

        2、汇编阶段

        vim arch/arm/kernel/head.S

        1)设置SVC模式、禁止IRQ中断、获取进程id、获取CPU id

        2)检测CPU id

        3)创建页表

        4)使能MMU

        5)清空BSS段,拷贝数据段

                vim arch/arm/kernel/head-common.S

        3、C语言阶段

        1)start_kernel()开始各种硬件初始化(更换了管理者,需要重新初始化)

        2)rest_init()处理剩下未处理完成的事情,证明我们现在还活着

        3)kernel_thread()创建一个内核线程

        4)kernel_init()在进行kernel初始化时,准备命名空间

        5)prepare_namespace()在命名空间里,挂载根文件系统

        6)kernel_init()挂载完根文件系统,初始化段,打开用户模式

        7)init_post()开始在用户模式跑起来

        8)执行后续进程、执行sh、执行用户输入的命令

        4、执行过程总结

                【1】入口点文件:arch/arm/kernel/head.S

                【2】设置SV管理模式

                【3】检查CPU-ID

                【4】创建页表

                【5】使能MMU

                【6】清空BSS,拷贝数据段

                【7】b start_kernel

                【8】rest_init()

                【9】创建内核线程

                【a】准备命名空间

                【b】挂载根文件系统

                【c】执行1号进程

                【d】执行后续进程

                【e】执行/bin/sh

                【f】执行用户输入的命令

        5、板子上电之后的执行流程

                1)执行uboot

                        【1】设置cpu为svc管理模式

                        【2】关闭看门狗,防止系统复位重启

                        【3】禁止L1 L2缓存,以及关闭MMU,使用物理地址

                        【4】检验CPU-ID是否合法,防止不法厂商

                        【5】清除BSS段

                        【6】打开MMU,使用虚拟地址

                        【7】跳转到board_init_f初始化硬件(关键!!!)

                        【8】跳转到board_init_r指定堆栈区域,初始化EMMC(关键!!!)

                        【9】main_loop

                        【a】cli_loop

                        【b】cli_simple_loop

                2)通过环境变量bootcmd找到内核,执行内核

                        【1】入口点文件:arch/arm/kernel/head.S

                        【2】设置SV管理模式

                        【3】检查CPU-ID

                        【4】创建页表

                        【5】使能MMU

                        【6】清空BSS,拷贝数据段

                        【7】b start_kernel

                        【8】rest_init()

                        【9】创建内核线程

                        【a】准备命名空间

                        【b】挂载根文件系统

                        【c】执行1号进程

                        【d】执行后续进程

                        【e】执行/bin/sh

                        【f】执行用户输入的命令

六、Makefile

        1)Makefile规则

                obj-y += xxx.o        // 将xxx.o文件编译进uImage

                obj-m += xxx.o       // 将xxx.o文件编译为一个独立的模块文件

                obj- += xxx.o          // 构建对象但不执行类型(不编译进uImage)

        2)=、:=、+=、?=

                =        // 最基本的赋值

                :=       // 覆盖之前的值

                ?=      // 如果之前没有赋值,就赋值等号后面的值

                +=      // 添加等号后边的值

        3)Kconfig、make menuconfig、.config、Makefile

Kconfigmake menuconfig.configMakefile
<*>=yobj-y
<m>=mobj-m
< >注释掉了obj-
添加menuconfig的选项

七、实操

        将led_drv.c编译进uImage

        1)拷贝文件到内核的字符设备目录中

                cp /mnt/hgfs/music/easthome_porting/led_drv.c ./drivers/char/                

        2)修改Makefile

                vim ./drivers/char/Makefile 

        3)制作Linux内核

                make uImage

        4)将编译好的uImage拷贝至tftpboot目录

                cp ./arch/arm/boot/uImage /tftpboot/

        5)下位机下载linux内核

                tftp 0x48000000 uImage

        6)将uImage写入emmc

                mmc write 48000000 2000 3000

        7)修改环境变量

                setenv bootcmd mmc read 48000000 2000 3000 \; bootm 48000000

        8)重启,进入内核,查看led_init是否被调用

                re:在uboot输入,重启开发板

                dmesg:在linux内核终端输入,查看内核的启动信息

        

                

  • 27
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值