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

相关文章

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

linux-基础知识3

打包和压缩 zip 安装zip软件包 yum -y install zip unzip 压缩打包命令: zip -q -r -d -u 压缩包文件名 目录和文件名列表 -q:不显示命令执行过程-r:递归处理,打包各级子目录和文件-u:把文件增加/替换到压缩包中-d:从压缩包中删除指定的文件 解压:unzip 压缩包名 打包文件 把压缩包从服务器下载到本地 把压缩包上传到服务器(zip

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

hdu4407(容斥原理)

题意:给一串数字1,2,......n,两个操作:1、修改第k个数字,2、查询区间[l,r]中与n互质的数之和。 解题思路:咱一看,像线段树,但是如果用线段树做,那么每个区间一定要记录所有的素因子,这样会超内存。然后我就做不来了。后来看了题解,原来是用容斥原理来做的。还记得这道题目吗?求区间[1,r]中与p互质的数的个数,如果不会的话就先去做那题吧。现在这题是求区间[l,r]中与n互质的数的和

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

Linux_kernel驱动开发11

一、改回nfs方式挂载根文件系统         在产品将要上线之前,需要制作不同类型格式的根文件系统         在产品研发阶段,我们还是需要使用nfs的方式挂载根文件系统         优点:可以直接在上位机中修改文件系统内容,延长EMMC的寿命         【1】重启上位机nfs服务         sudo service nfs-kernel-server resta

【Linux 从基础到进阶】Ansible自动化运维工具使用

Ansible自动化运维工具使用 Ansible 是一款开源的自动化运维工具,采用无代理架构(agentless),基于 SSH 连接进行管理,具有简单易用、灵活强大、可扩展性高等特点。它广泛用于服务器管理、应用部署、配置管理等任务。本文将介绍 Ansible 的安装、基本使用方法及一些实际运维场景中的应用,旨在帮助运维人员快速上手并熟练运用 Ansible。 1. Ansible的核心概念

Linux服务器Java启动脚本

Linux服务器Java启动脚本 1、初版2、优化版本3、常用脚本仓库 本文章介绍了如何在Linux服务器上执行Java并启动jar包, 通常我们会使用nohup直接启动,但是还是需要手动停止然后再次启动, 那如何更优雅的在服务器上启动jar包呢,让我们一起探讨一下吧。 1、初版 第一个版本是常用的做法,直接使用nohup后台启动jar包, 并将日志输出到当前文件夹n