Linux_kernel原理08

2024-09-06 11:52
文章标签 linux 原理 08 kernel

本文主要是介绍Linux_kernel原理08,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、温故知新

        系统移植

        1、uboot

                uboot主要做两件事:1、负责初始化硬件;2、负责引导操作系统的启动

        2、Linux内核

                Linux内核的五大功能

                【1】进程间通信

                【2】进程管理

                【3】网络子系统

                【4】虚拟文件子系统

                【5】内存管理

        3、根文件系统

                当Linux内核启动之后需要执行1号进程(init进程)

                1号进程对应的程序:cd ls cat touch cp。。。

                使用busybox工具制作自己的根文件系统

        4、开发板的烧写实验

                1)对emmc分区(按扇区进行访问)

                        EMMC的大小(8G)

                        根据uboot的大小来分区

                        根据uImage的大小来分区

                        根据rootfs的大小来分区

                mmc erase 0 0x100000

                tdisk 2 3 0x100000:0x4000000 0x4100000:0x2f200000 0x33300000:0

0M1M65M819M剩余空间
字节00x1000000x41000000x33300000剩余空间
ubootuboot-uImageuImage-rootfsrootfs-appapp
未分区未分区-mmcblk0p1mmcblk0p1-mmcblk0p2mmcblk0p2-mmcblk0p3mmcblk0p3
                2)烧写uboot

                cp ubootpak.bin /tftp_share/

                tftp 0x48000000 ubootpak.bin

                update_mmc 2 2ndboot 0x48000000 0x200 0x53ba8

注释:

        0x200 = 512byte = 1个扇区

                3)烧写uImage

                cp uImage /tftp_share/

                tftp 0x48000000 uImage

                mmc write 0x48000000 0x800 0x3000

                setenv bootcmd mmc read 48000000 800 3000 \; bootm 48000000

                4)烧写rootfs

                cp rootfs /tftp_share/

                tftp 0x48000000 rootfs

                mmc write 48000000 0x20800 0x32000

                setenv bootargs root=/dev/mmcblk0p2 rootfstype=ext4 console=ttySAC0,115200 maxcpus=1 lcd=wy070ml tp=gslx680

        5、通过nfs方式挂载根文件系统

        [1]上位机安装nfs服务

                sudo apt-get install nfs-kernel-server

        [2]创建nfs共享目录

                sudo mkdir /nfs_share

        [3]修改nfs共享目录的权限

                sudo chmod 777 /nfs_share

        [4]把根文件系统解压缩到nfs共享目录

                tar -xvf /nfs_share

        [5]修改配置文件

                sudo vim /etc/exports

                /nfs_share/rootfs *(rw,sync,no_root_squash)

        [6]修改服务文件

                sudo vim /etc/default/nfs-kernel-server

        [7]重启nfs服务

                sudo service nfs-kernel-server restart

                或

                sudo /etc/init.d/nfs-kernel-server restart

        [8]关闭防火墙

                sudo service ufw stop

                或

                sudo /etc/init.d/ufw stop

        [9]修改下位机的环境变量

                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

二、uboot的基本概念 

        1、通用的ubootloader

                类似于PC机上的BIOS

                【1】负责初始化硬件

                【2】负责引导操作系统的启动

                bootloader不属于操作系统内核的一部分,这部分的代码不具有可移植性,如我我们将来换了一块开发板,现在的uboot不一定可以直接使用。

        通用的含义:

                【1】:支持多种CPU架构:arm、mips、ppc、x86。。。

                【2】:支持多种类型的操作系统:Linux、windows、vxworks、RTOS。。。

        我们现在使用的就是支持ARM架构下Linux操作系统的bootloader

        2、ubootpak.bin从何而来?

                程序编译uboot源码得到ubootpak.bin

                1)uboot

                        uboot是非常著名的开源软件,但原始包里有很多我们今后开发不一定用到的资源

                        官网:DENX Software Engineering – the Embedded Linux Experts

                2)从上游厂商获取(从demo板中获取)

                        uboot.tar.gz

                        demo版本是芯片厂商提供的参考版本,可能方便使用,也可能不方便使用,所以我们需要做uboot开发的工程师进行修改或调试,让这个uboot可以在我们的开发板上完美的运行。

                3)获取并编译uboot源码

               /*将源码拷贝至实验目录*/

                cp /mnt/hgfs/easthome_porting/uboot.tar.gz ~/S5p6818/

                /*解压源码*/

                tar -xvf uboot.tar.gz

                cd uboot

                /*获取最干净的uboot源码*/

                make distclean

                /*获取uboot编译的配置文件*/

                make x6818_config

                /*对源码进行编译*/

                make

                4)修改uboot命令行的提示符

                vim  uboot/include/configs/x6818.h

                #define CONFIG_SYS_PROMPT        "zjd#"

                5)修改默认ip配置

                vim  uboot/include/configs/x6818.h

                #define CONFIG_NETMASK        255.255.255.0

                #define CONFIG_IPADDR            192.168.1.6

                #define CONFIG_SERVERIP       192.168.1.8

                #define CONFIG_GATEWAYIP     192.168.1.1

        3、uboot源码的目录结构

                uboot的目录大致分为3类

                【1】与处理器体系结构或者开发板硬件直接相关

                【2】一些通用的函数或驱动程序

                【3】是uboot的应用程序\工具\文档

1)api

(应用程序编程接口)

独立于体系架构之外的功能函数接口,一般是uboot本身使用的,uboot在移植的时候基本不用动。

2)arch(Architecture)

体系架构

包含了特定的处理器架构的代码,如:ARM、PPC、MIPS、X86等

        arch/arm 在arch目录下现在只剩下arm了,已经被上游厂商裁剪过了。

        arch/arm/cpu:存放了和cpu紧密相关的内容

        arch/arm/cpu/slsiap:存放了三星公司的工程内容

        arch/arm/cpu/slsiap/s5p6818:有关s5p6818芯片的内容

3)board开发板相关的配置文件存放与开发板相关的代码,如:初始化脚本、设备树等
4)common通用的

包含大多数uboot的代码使用的通用函数

       主要是两类:1、实现uboot的命令;2、实现环境变量

5)disk硬盘提供硬盘驱动的位置,用于文件系统的读写操作
6)doc文档包含uboot的文档
7)drivers驱动

包含各种设备的驱动程序,如:网络驱动程序\显示驱动程序。。。

存放的是从Linux内核源码中拷贝过来的Linux设备驱动

主要是uboot在启动时所支持的硬件的驱动

其实uboot在一定程度上移植了Linux驱动

8)dts设备树提供设备树工具
9)examples示例代码提供了一些示例代码,如:使用uboot的命令,使用uboot的API
a)fs文件系统里面存放了支持的文件系统类型
b)include头文件里面存放了各种常用函数的头文件
c)lib库里面存放了各种常用函数的实现
d)net有关网络包含网络相关的代码,如:nfs、tftp
e)post上电自检属于硬件自检的操作
f)scripts包含用于编译uboot的脚本
g)test测试提供测试代码,用于验证uboot的功能
h)tools工具包含用于处理uboot镜像的工具

我们可以将uboot认为是一个巨大无比的裸板程序,几乎在uboot的每一级目录下都有一个makefile文件,决定了当前目录下,哪些文件参与编译,哪些不参与编译,那些需要重新编译。

uboot/common/Makefile

        4、找到uboot的入口点文件

                C程序的启动与终止

                【1】内核通过exec——族函数调用C启动例程

                【2】C启动例程再调用main函数,进程开始运行

                【3】main函数return就返回到了C启动例程

                【4】C启动例程需要调用exit(3)函数

                        注意:C启动例程不能直接返回给内核

                【5】exit(3)再调用_exit(2)或者_Exit(2)函数返回给内核进程才会结束

                        注意:内核预留的终止进程的函数结构是_exit(2)或_Exit(2)

                【6】exit(3)函数在调用_exit(2)或_Exit(2)函数之前还会调用其他的函数接口,比如标准IO的清理程序(清缓冲区)

                1) 查找源码的入口点文件(法一)

                gcc -v        // 查看gcc版本

                make -v        // 查看make版本

                arm-cortex_a9-linux-gnueabi-gcc -v        // 查看交叉编译工具链版本

                make V=1        // V=1将编译链接的详细过程展示出来

        /*查看最后的链接*/

                arm-cortex_a9-linux-gnueabi-ld.bfd -pie --gc-sections -Bstatic -Ttext 0x43C00000 -o u-boot -T u-boot.lds arch/arm/cpu/slsiap/start.o

        /*这里的start.o是.c文件还是.s文件*/

        /*是.s文件,因为在初始化硬件初期时,内存没有被初始化,不能是.c文件,由此确定*/

        /*入口点文件是start.S文件*/

                2) 查找源码的入口点文件(法二)

        /*通过查看链接脚本文件,确定入口点*/

        vim uboot/u-boot.lds //连接脚本

/*文件内容*/

arch/arm/cpu/slsiap/s5p6818/start.o 入口点目标文件

arch/arm/cpu/slsiap/s5p6818/start.S 入口点文件

/*发现于法一的结果不同,以链接脚本文件为准,由此确定*/

 /*入口点文件是arch/arm/cpu/slsiap/s5p6818/start.S文件*/

        5、uboot的执行流程 

        【1】vim arch/arm/cpu/slsiap/s5p6818/start.S

        【2】设置cpu为SVC管理模式

        【3】关闭看门狗

        【4】禁止L1 L2缓存,关闭MMU内存管理单元

                关闭MMU内存管理单元的目的:要使用物理地址

        【5】回到被调用的位置

        【6】跳转到cpu_init_crit

        【7】跳转到lowlevel_init

        【8】vim arch/arm/cpu/slsiap/s5p6818/low_init.S

        【9】跳转到clear_bss

        【10】先打开MMU内存管理单元,再清除bss段

                打开MMU内存管理单元的目的:可以使用虚拟地址,MMU在不断的更新物理地址和虚拟地址的映射

        【11】跳转到board_init_f

        【12】vim arch/arm/lib/board.c

        【13】board_init_f(重要!!!)

                它完成了一系列硬件的初始化

                如:cpu、uart、display、env。。。

        init_fnc_ptr:指向各硬件初始化函数的指针

        init_sequence:一个函数指针数组,包含着各硬件初始化函数的入口地址

经过一边循环,就可以对所有保存在数组里的硬件进行初始化

        【14】跳转到board_init_r

        【15】vim arch/arm/lib/board.c

        【16】board_init_r(重要!!!)

                它指定堆栈的区域,对EMMC进行初始化

        【17】main_loop()可以返回自动引导,如果已经引导了,那就再引导一次

        【18】cli_loop()

        【19】cli_simple_loop()

        6、总结

                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)修改默认配置

                        include/config/x6818.h

                【a】波特率

                【b】命令行提示符

                【c】各种环境变量

三、uboot中添加启动logo

        我们可以在所有的显示类设备增加一个启动logo(商业行为)

LCD、OLED、段码屏、数码管、点阵屏、LED灯、水立方

        1、显示原理 

        2、图像的构成

                图像是由一个一个像素点构成

                三原色

                16位色:RGB565

                32位色:RGB888【0~255】(前8位保留)

                红色:0x00FF0000

                绿色:0x0000FF00

                蓝色:0x000000FF

                白色:0xFFFFFFFF

                黑色:0x00000000

        3、LCD的分辨率

                7寸的LCD液晶显示屏

                lcd的分辨率 1024 * 600

                lcd的显存地址是由三星公司规定的0x46000000

                vim uboot/include/configs/x6818.h

                计算lcd对应点的地址P0(x0, y0)

                /*将P0点设置为红色*/

                *(volatile unsigned int *)(0x46000000 + ((y0 * 1024) + x0) * 4) = 0x00FF000000

        4、将图片转换为RGB

                工具位置:easthome_poriting\u-boot-logo\tools\Image2Lcd\Img2Lcd.exe 

        5、实验步骤

                1】将生成的子模文件拷贝至uboot目录

                cp logo.c uboot/common

                2】编写画点及画logo的函数

                vim uboot/common/draw_logo.c

#define LCD_BASE 0x46000000
#define WIDTH    1024
#define HIGHT    600
#define X0       0
#define Y0       0
#define LOGO_W   1024
#define LOGO_H   600extern const unsigned char gImage_logo[];void draw_pixel(int row, int col, int color)
{*(int *)(LCD_BASE + ((row * WIDTH) + col) * 4) = color;
}void lcd_draw_logo(void)
{int i = 0, j = 0;unsigned int blue = 0;unsigned int green = 0;unsigned int red = 0;unsigned int color = 0;const unsigned char *p = gImage_logo;for(i = Y0; i < (Y0 + LOGO_H); i++) {for(j = X0; j < (X0 + LOGO_W); j++) {blue = *p++;green = *p++;red = *p++;color = red << 16 | green << 8 | blue;draw_pixel(i, j, color);}}}
                3】添加调用画logo的函数

                vim uboot/arch/arm/cpu/slsiap/common/cmd_draw_logo.c

                4】修改Makefile文件

                vim uboot/common/Makefile

                5】编译uboot

                1]make distclean

                2]make x6818_config

                3]make

                6】烧写uboot

                1]上位机把新生成的ubootpak.bin文件拷贝到tftp共享目录中

                        cp ubootpak.bin /tftpboot

                2]下位机下载uboot

                        tftp 48000000 ubootpak.bin

                3]更新emmc

                        update_mmc 2 2ndboot 48000000 200 [下载的字节数]

                4]重启uboot

                        re

这篇关于Linux_kernel原理08的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1141931

相关文章

高效管理你的Linux系统: Debian操作系统常用命令指南

《高效管理你的Linux系统:Debian操作系统常用命令指南》在Debian操作系统中,了解和掌握常用命令对于提高工作效率和系统管理至关重要,本文将详细介绍Debian的常用命令,帮助读者更好地使... Debian是一个流行的linux发行版,它以其稳定性、强大的软件包管理和丰富的社区资源而闻名。在使用

Redis主从/哨兵机制原理分析

《Redis主从/哨兵机制原理分析》本文介绍了Redis的主从复制和哨兵机制,主从复制实现了数据的热备份和负载均衡,而哨兵机制可以监控Redis集群,实现自动故障转移,哨兵机制通过监控、下线、选举和故... 目录一、主从复制1.1 什么是主从复制1.2 主从复制的作用1.3 主从复制原理1.3.1 全量复制

Linux Mint Xia 22.1重磅发布: 重要更新一览

《LinuxMintXia22.1重磅发布:重要更新一览》Beta版LinuxMint“Xia”22.1发布,新版本基于Ubuntu24.04,内核版本为Linux6.8,这... linux Mint 22.1「Xia」正式发布啦!这次更新带来了诸多优化和改进,进一步巩固了 Mint 在 Linux 桌面

LinuxMint怎么安装? Linux Mint22下载安装图文教程

《LinuxMint怎么安装?LinuxMint22下载安装图文教程》LinuxMint22发布以后,有很多新功能,很多朋友想要下载并安装,该怎么操作呢?下面我们就来看看详细安装指南... linux Mint 是一款基于 Ubuntu 的流行发行版,凭借其现代、精致、易于使用的特性,深受小伙伴们所喜爱。对

Redis主从复制的原理分析

《Redis主从复制的原理分析》Redis主从复制通过将数据镜像到多个从节点,实现高可用性和扩展性,主从复制包括初次全量同步和增量同步两个阶段,为优化复制性能,可以采用AOF持久化、调整复制超时时间、... 目录Redis主从复制的原理主从复制概述配置主从复制数据同步过程复制一致性与延迟故障转移机制监控与维

什么是 Linux Mint? 适合初学者体验的桌面操作系统

《什么是LinuxMint?适合初学者体验的桌面操作系统》今天带你全面了解LinuxMint,包括它的历史、功能、版本以及独特亮点,话不多说,马上开始吧... linux Mint 是一款基于 Ubuntu 和 Debian 的知名发行版,它的用户体验非常友好,深受广大 Linux 爱好者和日常用户的青睐,

Linux(Centos7)安装Mysql/Redis/MinIO方式

《Linux(Centos7)安装Mysql/Redis/MinIO方式》文章总结:介绍了如何安装MySQL和Redis,以及如何配置它们为开机自启,还详细讲解了如何安装MinIO,包括配置Syste... 目录安装mysql安装Redis安装MinIO总结安装Mysql安装Redis搜索Red

SpringCloud配置动态更新原理解析

《SpringCloud配置动态更新原理解析》在微服务架构的浩瀚星海中,服务配置的动态更新如同魔法一般,能够让应用在不重启的情况下,实时响应配置的变更,SpringCloud作为微服务架构中的佼佼者,... 目录一、SpringBoot、Cloud配置的读取二、SpringCloud配置动态刷新三、更新@R

Linux中Curl参数详解实践应用

《Linux中Curl参数详解实践应用》在现代网络开发和运维工作中,curl命令是一个不可或缺的工具,它是一个利用URL语法在命令行下工作的文件传输工具,支持多种协议,如HTTP、HTTPS、FTP等... 目录引言一、基础请求参数1. -X 或 --request2. -d 或 --data3. -H 或

Linux磁盘分区、格式化和挂载方式

《Linux磁盘分区、格式化和挂载方式》本文详细介绍了Linux系统中磁盘分区、格式化和挂载的基本操作步骤和命令,包括MBR和GPT分区表的区别、fdisk和gdisk命令的使用、常见的文件系统格式以... 目录一、磁盘分区表分类二、fdisk命令创建分区1、交互式的命令2、分区主分区3、创建扩展分区,然后