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内核终端输入,查看内核的启动信息

        

                

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/53504.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vscode从本地安装插件

1. 打开VSCode。 2. 点击左侧菜单中的“扩展”&#xff08;或按CtrlShiftX&#xff09;。 3. 点击“更多操作”&#xff08;三个点&#xff09;> “从VSIX安装”。 4. 选择下载的.vsix文件。 5. 点击“安装”即可安装插件。

传统CV算法——基于Opencv的图像绘制

直线绘制 参数解析&#xff1a; &#xff08;图像矩阵&#xff0c;直线起始坐标&#xff0c; 直线终止坐标、颜色、线条厚度&#xff09; cv2.line()是OpenCV中用于绘制直线的函数。 参数说明&#xff1a;img&#xff1a;要绘制直线的图像矩阵。(100,30)&#xff1a;直线的起…

视频提取字幕的软件有哪些?高效转录用这些

探索视频的奥秘&#xff0c;从字幕开始&#xff01;你是否曾被繁复的字幕处理困扰&#xff0c;渴望有一款简单好用的在线免费软件来轻松解锁字幕提取&#xff1f; 告别手动输入的烦恼&#xff0c;我们为你精选了6款视频字幕提取在线免费软件&#xff0c;它们不仅能一键转录&am…

堆-数组的堆化+优先队列(PriorityQueue)的使用

一、堆 1、什么是堆&#xff1f; 以完全二叉树的形式将元素存储到对应的数组位置上所形成的新数组 2、为什么要将数组变成堆&#xff1f; 当数组中的元素连续多次进行排序时会消耗大量的时间&#xff0c;将数组变成堆后通过堆排序的方式将会消耗更少的时间 二、接口 给堆…

这才是程序猿梦想的终端,赶快动手搞起来

文章目录 目标资源列表安装iTerm2安装oh-my-zsh安装颜色主题查找配置文件将配置内容复制到本地设置iTerm2 安装NERD FONTS下载字体安装设置iTerm2 安装PowerLevel10k修改.zshrc重新加载配置 安装插件下载[语法高亮](#syntaxhighlighting)下载[命令提示](#autosuggestions)配置插…

数据结构与算法02 - 复杂度

1、空间复杂度 空间复杂度指的是临时占用存储空间大小的量度&#xff1b;空间复杂度计算的是变量的个数&#xff0c;也采用大O渐进表示法&#xff1b;由于函数在运行的时候所需要的栈空间&#xff08;存储参数、局部变量、一些寄存器信息等&#xff09;在编译器已经确定好了&a…

Kafka【十二】消费者拉取主题分区的分配策略

【1】消费者组、leader和follower 消费者想要拉取主题分区的数据&#xff0c;首先必须要加入到一个组中。 但是一个组中有多个消费者的话&#xff0c;那么每一个消费者该如何消费呢&#xff0c;是不是像图中一样的消费策略呢&#xff1f;如果是的话&#xff0c;那假设消费者组…

MySQL 锁分类有哪些?一文带你详解!!

MySQL 锁 全局锁全局锁的应用场景全局锁的缺点 表级锁表锁元数据&#xff08;MDL&#xff09;锁MDL 锁的问题 意向锁AUTO-INC 锁 行级锁记录锁&#xff08;Record Lock&#xff09;间隙锁&#xff08;Gap Lock&#xff09;临键锁&#xff08;Next-Key Lock&#xff09;插入意向…

Opencv中的直方图(2)计算图像的直方图函数calcHist()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 计算一组数组的直方图。 函数 cv::calcHist 计算一个或多个数组的直方图。用于递增直方图bin的元组的元素是从相同位置的相应输入数组中获取的。…

Cursor是什么?Cursor Pro Plus 如何订阅升级教程

一、Cursor是什么&#xff1f; Cursor 是一个基于 Visual Studio Code&#xff08;VS Code&#xff09;技术构建的高级代码编辑器&#xff0c;专为提高编程效率并更深度地整合 AI 功能而设计。它不仅继承了 VS Code 的强大功能和用户界面&#xff0c;还增加了专门针对 AI 支持…

Agent(智能体)和 MetaGPT,一句话实现整个需求应用代码

前面 2 篇文章&#xff0c;我们使用文生文、文生图和文生音频三个大模型共同实现了图文并茂的儿童绘本故事和绘本故事音频需求&#xff1a; 第一篇 根据主题生成儿童绘本故事&#xff1a;GLM-4-Flash 大模型 API 免费了&#xff0c;手把手构建“儿童绘本”应用实战&#xff08…

Nuxt3入门:过渡效果(第5节)

你好同学&#xff0c;我是沐爸&#xff0c;欢迎点赞、收藏、评论和关注。 Nuxt 利用 Vue 的 <Transition> 组件在页面和布局之间应用过渡效果。 一、页面过渡效果 你可以启用页面过渡效果&#xff0c;以便对所有页面应用自动过渡效果。 nuxt.config.js export defaul…

概率DP (由一道绿题引起的若干问题。目前为一些老题,蒟蒻的尝试学习1.0)

概率DP&#xff1a; 利用动态规划去解决 概率 期望 的题目。 概率DP 求概率&#xff08;采用顺推&#xff09; 从 初始状态推向结果&#xff0c;同一般的DP类似&#xff0c;只是经历了概率论知识的包装。 老题&#xff1a; 添加链接描述 题意&#xff1a; 袋子里有w只白鼠&am…

linux编译器——gcc/g++

1.gcc linux上先要安装&#xff0c; sudo yum install gcc gcc --version 可以查看当前的版本 &#xff0c;我们默认安装的是4.8.5的版本&#xff0c;比较低&#xff0c; gcc test.c -stdc99 可以使他支持更高版本的c标准 -o 可以殖指明生成文件的名字&#xff0c;可以自己…

跨越技术壁垒:EasyCVR为何选择支持FMP4格式,重塑视频汇聚平台标准

随着物联网、大数据、云计算等技术的飞速发展&#xff0c;视频监控系统已经从传统的安防监控扩展到智慧城市、智能交通、工业制造等多个领域。视频流格式作为视频数据传输与存储的基础&#xff0c;其兼容性与效率直接影响到整个视频监控系统的性能。 在众多视频流格式中&#…

TCP Analysis Flags 之 TCP Port numbers reused

前言 默认情况下&#xff0c;Wireshark 的 TCP 解析器会跟踪每个 TCP 会话的状态&#xff0c;并在检测到问题或潜在问题时提供额外的信息。在第一次打开捕获文件时&#xff0c;会对每个 TCP 数据包进行一次分析&#xff0c;数据包按照它们在数据包列表中出现的顺序进行处理。可…

十大口碑最好开放式蓝牙耳机是哪些?五款热销好用产品测评!

​开放式耳机现在超火&#xff0c;成了时尚、好看又舒服的代名词&#xff0c;迅速俘获了一大波粉丝&#xff0c;成了耳机界的新宠儿。跟那些传统的入耳式耳机比起来&#xff0c;开放式耳机戴着更稳&#xff0c;对耳朵也更友好。不过&#xff0c;也有人觉得这玩意儿不值&#xf…

系统找不到指定的文件怎么解决?

把U盘插在电脑上&#xff0c;当我打开U盘中的文件时&#xff0c;弹窗提示系统找不到指定的文件&#xff0c;这是什么情况&#xff1f;有谁遇到过吗&#xff1f;大家有没有解决办法&#xff1f; 这个问题可能大家并不陌生&#xff0c;可能也曾遇到过&#xff0c;造成问题出现的原…

现代计算机中数字的表示与浮点数、定点数

现代计算机中数字的表示与浮点数、定点数 导读&#xff1a;浮点数运算是一个非常有技术含量的话题&#xff0c;不太容易掌握。许多程序员都不清楚使用操作符比较float/double类型的话到底出现什么问题。这篇文章讲述了浮点数的来龙去脉&#xff0c;所有的软件开发人员都应该读…

sqli-lab靶场学习(一)——Less1-4

前言 最近一段时间想切入安全领域&#xff0c;因为本身有做数据库运维工作&#xff0c;就打算从sql注入方向切入。而sql注入除了学习日常书本上的概念外&#xff0c;需要有个实践的环境&#xff0c;刚好看到sqli-lab这个靶场&#xff0c;就打算先用这个来学习。 安装部署 网上…