嵌入式系统启动文件及其流程的理解

简单概括总结嵌入式上电启动顺序

·启动第1步:加载BIOS
当你打开计算机电源,计算机会首先加载BIOS信息,BIOS信息是如此的重要,以至于计算机必须在最开始就找到它。这是因为BIOS中包含了CPU的相关信息、设备启动顺序信息、硬盘信息、内存信息、时钟信息、PnP特性等等。在此之后,计算机心里就有谱了,知道应该去读取哪个硬件设备了。
启动第2步:读取MBR
硬盘上第0磁道第一个扇区被称为MBR,也就是Master Boot Record,即主引导记录,它的大小是512字节,别看地方不大,可里面却存放了预启动信息、分区表信息。系统找到BIOS所指定的硬盘的MBR后,就会将其复制到0x7c00地址所在的物理内存中。其实被复制到物理内存的内容就是Boot Loader,而具体到你的电脑,那就是lilo或者grub了。
启动第3步:Boot Loader
Boot Loader 就是在操作系统内核运行之前运行的一段小程序。通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核做好一切准备。Boot Loader有若干种,其中Grub、Lilo和spfdisk是常见的Loader。系统读取内存中的grub配置信息(一般为menu.lst或grub.lst),并依照此配置信息来启动不同的操作系统。
启动第4步:加载内核
根据grub设定的内核映像所在路径,系统读取内存映像,并进行解压缩操作。此时,屏幕一般会输出“Uncompressing Linux”的提示。当解压缩内核完成后,屏幕输出“OK, booting the kernel”。系统将解压后的内核放置在内存之中,并调用start_kernel()函数来启动一系列的初始化函数并初始化各种设备,完成Linux核心环境的建立。至此,Linux内核已经建立起来了,基于Linux的程序应该可以正常运行了。
启动第5步:用户层init依据inittab文件来设定运行等级内核被加载后,第一个运行的程序便是/sbin/init,该文件会读取/etc/inittab文件,并依据此文件来进行初始化工作。其实/etc/inittab文件最主要的作用就是设定Linux的运行等级,其设定形式是“:id:5:initdefault:”,这就表明Linux需要运行在等级5上。
启动第6步:进程执行rc.sysinit
在设定了运行等级后,Linux系统执行的第一个用户层文件就是/etc/rc.d/rc.sysinit脚本程序,它做的工作非常多,包括设定PATH、设定网络配置(/etc/sysconfig/network)、启动swap分区、设定/proc等等,可以到/etc/rc.d中查看一下rc.sysinit文件.
启动第7步:启动内核模块
具体是依据/etc/modules.conf文件或/etc/modules.d目录下的文件来装载内核模块。
启动第8步:执行不同运行级别的脚本程序
根据运行级别的不同,系统会运行rc0.d到rc6.d中的相应的脚本程序,来完成相应的初始化工作和启动相应的服务。
启动第9步:执行/etc/rc.d/rc.local打开了此文件,里面有一句话,
# This script will be executed *after* all the other init scripts.
# You can put your own initialization stuff in here if you don’t
# want to do the full Sys V style init stuff.
rc.local就是在一切初始化工作后,Linux留给用户进行个性化的地方。你可以把你想设置和启动的东西放到这里。
启动第10步:执行/bin/login程序,进入登录状态
此时,系统已经进入到了等待用户输入username和password的时候了,你已经可以用自己的帐号登入系统了。

 

 

一,明确嵌入式linux系统软件启动流程
     ->硬件上电  

    ->  CPU自动运行Nand的u-boot(属于bootloader的一种) u-boot运行

     ->  u-boot会从"某个地方"将kernel内核加载到内存的某个地址,加载完以后,

           并且uboot从内存的这个地址启动kernel内核,给内核传递启动参数  

    ->内核一旦启动,uboot的生命周期结束  

    ->内核开始玩命运行,运行到最后 

    -> 根据uboot传递的启动参数,去到"某个地方"去挂接(找)根文件系统rootfs

    -> 一旦找到,内核至此把控制权交给根文件系统rootfs的第一号进程sbin/init

    ->第一号进程启动,创建一个子进程,子进程运行shell程序(bin/sh) 接下来就开始接收和处理用户输入的命令(ls...)
   注意:如果内核和rootfs烧写Nand,笔记提及“某个地方“就是指Nand的某个分区

二,uboot相关

 1,bootloader:

  特点:

       (1).启动代码,本质就是一个裸板程序

        (2).bootloader统称,u-boot属于bootloader的一种类似PC的BIOS!

        (3).下位机上电运行的第一个程序!

        (4).烧写到闪存(Nand)的0地址开始

   功能:

        用来加载linux操作系统内核kernel到内存,并且从内存中启动linux内核,最后给内核传递启动参数,

        告诉内核,你将来要挂接的根文件系统rootfs在哪里 

2, 首先明确uboot的功能:
     从某个地方加载内核到内存,并且从内存中启动内核,并且给内核传递的启动参数,告诉内核,根文件系统在哪里;
     然后明确uboot的生命周期:
     上电CPU自动开始运行 / 内核启动结束

3,  uboot所做的工作:

      观察make编译最后的链接过程,肯定指定了链接脚本的路径和程序运行的基地址!

       通过链接脚本获取到运行的第一个文件:start.S

       通过链接脚本获取到运行的第一个入口:_start

 

bootloader 是系统的一个引导程序,可以用于调试升级系统。可以是EBOOT \UBOOT\ SERIL BOOT等待其他一切方式。

Eboot 是使用网口的意思,UBOOT 是使用USB口的意思,SERIL BOOT 是串口,但是现在很多BSP时间上都是在EBOOT的基础上修改的,加上了usb部分或其他的功能,我们的bootloader虽然是名字是EBOOT 但实际上就没有网口的功能。

3.1,uboot的第一阶段——初始化硬件

         start.S :汇编实现的阶段,此阶段通常称之第一阶段

       (1).初始化CPU(Cache,MMU,关闭中断)

       (2).初始化内存(内存控制器)

       (3).初始化闪存(Nand控制器)

       (4).初始化时钟(时钟控制器)时钟源:24MHz / APLL:1G/...

       (5).关闭看门狗(看门狗控制器)

       (6).初始化UART

       (7).初始化LCD

注意:并不是所有的硬件都需要在uboot中进行初始化,哪些初始化,那些不初始化完全根据用户的实际需求,如路由器

   3.2  正式进入uboot的C语言实现的阶段,此阶段通常称之为第二阶段

         ldr pc, _start_armboot

         _start_armboot:

         .word start_armboot

          uboot继续运行,执行对应的C语言实现的代码:start_armboot:lib_arm/board.c

          典型代码:

   for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr)

   {

            if ((*init_fnc_ptr)() != 0)

          {

            hang ();

           }

  } //此循环中做了各种init工作!

 

  4,移植(修改)uboot的关注点:

  在init_sequence它中有一个函数指针board_init此函数里面做了根开发板硬件相关的初始化代码将来可以将自己的硬件初始化添加在此函数中调用即可。注意:board_init函数将来要必看!

  最后跑到一个死循环:

  for (;;) {      main_loop ();      }

 main_loop()

{

  s = getenv("bootcmd");

  //如果3秒以内没有键盘操作

  run_command(s, 0);//执行bootcmd的命令

  //如果有键盘操作,最后进入

    for (;;)

   {

      readline(s);//读取用户输入的命令

      run_commond(s, 0);//执行uboot的命令

     }

 }

总结:uboot的代码执行

A.先运行start.S      入口:_start(汇编实现)

B.再运行board.c    入口:start_armboot(C语言实现)

5,查看所有的uboot命令

        help 命令名:查看命令的帮助

        print //打印环境变量关键环境变量:

        ipaddr:下位机的ip

        serverip:上位机的ip以上两个ip需要在同一个网段

        bootcmd:内核启动

        bootargs:内核传参

        setenv  //修改环境变量

        setenv bootcmd ...

        saveenv  //保存修改的环境变量

       ping  //检查网卡的物理连接

       tftp  //tftp文件下载

       nand erase/write/read

       reset 重启

       boot 启动,本质就是执行bootcmd的命令

       md:读取外设的数据并打印显示

       mw. 向外设写入数据

三, linux操作系统内核(kernel):

1,  特点:

   (1)linux系统的核心

   (2)操作系统内核由bootloader加载启动类似windows由BIOS加载引导。

   (3)内核启动以后,运行到最后,根据bootloader传递过来的参数,内核根据此参数,去到 “某个地方”找根文件系统rootfs,

           找到以后,执行根文件系统rootfs中的第一号进程init,最后init第一号进程创建一个子进程来运行sh程序(shell),

           接收和处理用户输入的命令,例如ls,cd,mkdir等,至此linux系统运行完毕!

   (4)烧写到Nand上           

        功能:7大子系统          进程管理子系统 —— 进程的创建,调度,抢占,销毁
          内存管理子系统 —— 内存的分配,映射,销毁
          网络协议栈 —— 除了物理层,其它层的软件
          文件系统 —— EXT4/EXIT3/EXT2/FAT32/NTFS/CRAMFS/YAFFS2/UBIFS/RAMDISK
          设备驱动 —— 硬件设备驱动程序
          系统调用 —— open/close/read/write/brk/sbrk/mmap/fork/exit/...
          平台相关代码 —— 这些代码能够让linux运行在X86,ARM/powerpc/mips/fpga/dsp这些主流的硬件上
      2,设置内核的启动参数
      重启开发板,进入uboot的命令行模式:
         setenv bootcmd nand read  50008000 500000 500000 \; bootm 50008000
         saveenv  //保存环境变量bootcmd的值
说明:bootcmd:此环境变量的功能用于uboot起来以后,如果用户在3秒以内没有进行键盘操作,3秒以后uboot会自动执行bootcmd对应的命令:nand read 50008000 500000 500000 ; bootm 50008000
说明:将内核从Nand的5M开始,读5M到内存的 0x50008000地址,然后再利用bootm命令从内存的0x50008000启动内核,内核就开始玩命的运行了
总结:从Nand加载内核到内存,并且启动内核
         setenv bootargs root=/dev/mtdblock3 init=/init console=ttySAC0,115200
         saveenv
说明:bootargs:此环境变量的作用是用于给内核传递启动参数告诉内核,根文件系统rootfs在哪里设置的参数信息为:root=/dev/mtdblock3 init=/init console=ttySAC0,115200 (SAC0,115200不能有空格)
说明:root=/dev/mtdblock3:告诉内核,根文件系统rootfs在Nand的第四分区‘;

           init=/init:一旦找到了根文件系统rootfs,启动的第一号进程在根文件系统rootfs的/init,运行此程序;

          console=ttySAC0,115200:指定内核启动时打印输出信息,使用的串口为第一个串口ttySAC0,

          指定的波特率为115200重启开发板,就不要操作键盘,3秒以后系统启动!等待着系统的起来!

3,Kconfig的使用语法

         作用:仅仅生成一个选项,生成的选项给对应的Makefile使用,Makefile根据选项最终决定内核程序如何编译

         例子:

         cd /opt/kernel

         vim drivers/char/Kconfig

         config HELLOWORLD

         tristate "hello, world"

         help

         this is a test

         说明:

         config关键字用来生成一个选项CONFIG_HELLOWORLD(注意别忘记CONFIG_)

         此选项CONFIG_HELLOWORLD给将来编译内核程序的Makefile使用

4,   tristate关键字,指示此选项的操作方式有三种:

         (1).按Y选择为*,最终导致CONFIG_HELLOWORLD=y表示此选项对应的内核程序helloworld.c将会和zImage编译在一起("在一起")

         (2).按M选择为M,最终导致CONFIG_HELLOWORLD=m表示此选项对应内核程序helloworld.c不会和zImage编译在一起,需要进行单独编译(分家)

         (3).按N不选择,不选择也就不编译,CONFIG_HELLOWORLD=空

5,驱动内容对应硬件简介

              System Type  --->

              //说明当前内核支持ARM架构,支持三星S5PV210处理器

              ARM system type (Samsung S5PV210/S5PC110)  --->

              //指定内核启动的打印输出信息用哪个串口

              (0) S3C UART to use for low-level messages  

              //选择某个开发板,一般选择参考板即可,让内核支持当前的开发板

              Board selection (SMDKV210)  --->   

         

             Boot options  --->     

            //此选项的内容就是将来内核启动的参数,内核根据

            此参数去挂接根文件系统rootfs

            (console=ttySAC2,115200) Default kernel command string

            

            //如果此选中选中(按Y选择为*),那么内核启动的参数是内核自己传递

            就是上面的选项

            //如果此选项没选([]里面为空),那么内核启动的参数用

            uboot的bootargs

            [ ]Always use the default kernel command string

     

              Device Drivers  --->

                //Nand和Nor的驱动

                //*:包含此驱动,空就是不支持此驱动

                <*> Memory Technology Device (MTD) support  --->

                //网络设备驱动(有线和无线网卡)

                [*] Network device support  --->

                //键盘,鼠标,触摸屏,游戏手柄,摇杆

                Input device support  --->  

             //I2C总线驱动支持

             <*> I2C support  --->

             //SPI总线驱动支持

             [*] SPI support  --->

             //一线式总线驱动支持

             <*> Dallas's 1-wire support  --->   

             //看门狗驱动支持

             [*] Watchdog Timer Support  --->

             //摄像头驱动支持

             <*> Multimedia support  --->  

             //LCD显示屏驱动支持

             Graphics support  --->

             //声卡驱动

              <*> Sound card support  --->

               //USB相关驱动

               [*] USB support  --->   

             //SD卡驱动

             <*> MMC/SD/SDIO card support  --->  

    

        File systems  --->       

         [*] Miscellaneous filesystems  --->       

            //Nand常用yaffs2文件系统,可以读写

            <*>YAFFS2 file system support

               //Norflash常用jffs2文件系统,可以读写

               <*>Journalling Flash File System v2 (JFFS2) support    

               //Nand和Nor都可以,此文件系统只能读不能写

               <*>Compressed ROM file system support (cramfs)

           

            [*] Network File Systems  --->

              //如果此选项不选,内核通过NFS网络挂接根文件系统就没门

              [*]Root file system on NFS  

 

四,根文件系统(rootfs): 

  特点:

 (1).最后要执行的软件

 (2).内核去挂接(找)根文件系统rootfs,根据bootloader传递的参数

        明确:根文件系统rootfs仅仅是一个代名词而已里面包含了一堆的应用程序(ls),

       一堆的动态库(libc.so)和静态库(libc.a),一堆的配置文件(/etc/init.d/tftpd-hpa)而已!

 (3)烧写到Nand上

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

python使用win32库模拟拖拽文件发给指定窗口

最近要用python模拟人的操作给窗口发送拖拽文件的消息&#xff0c;网上搜了一大圈也没搜到现成可用的代码。幸好以前做过vc开发&#xff0c;熟悉点win32编程&#xff0c;于是装上vs和msdn&#xff0c;从消息WM_DROPFILES查起&#xff0c;慢慢得实现了这个功能。 WM_DROPFILES是…

TMS FNC UI Pack 3.1Crack,四个框架和五个操作系统的强大控件

TMS FNC UI Pack是TMS软件的产品&#xff0c;具有针对四个框架和五个操作系统的强大控件和丰富功能。 TMS FNC控件可以在以下框架中同时使用&#xff1a; TMS FNC控件可以在以下操作系统/浏览器中同时使用&#xff1a; TMS FNC控件可在以下IDE中同时使用&#xff1a; TMS FNC U…

TMS FNC组件crack,TMS FNC跨平台的图形组件

TMS FNC组件crack,TMS FNC跨平台的图形组件 TMS FNC Chart 为公司、统计、财政和科学信息开发的完全跨平台的图形组件。 TMS FNC 组件可以在这些框架上同时使用。 TMS FNC 组件可以在这些操作系统/浏览器上同时使用。 TMS FNC 控件可以在这些 IDE 上同时使用。 TMS FNC图表应用…

开源代码扫描工具 Socket新增对 Go 生态系统的支持

导读继日前宣布完成 2000 万美元的 A 轮融资后&#xff0c;开源代码扫描工具 Socket 紧接着宣布新增了对 Go 语言的支持&#xff1b;此前其仅支持 JavaScript 和 Python 语言。 “在过去的几个月中&#xff0c;我们观察到针对 Golang 的供应链攻击有所增加。意识到这种迫在眉睫…

Python数据分析的bs4用法

在爬虫的世界里&#xff0c;数据解析占用很重要的位置 数据解析原理&#xff1a; 标签定位提取标签、标签属性中存储的数据值 bs4数据解析原理&#xff1a; 1.实例化一个BeautifulSoup对象&#xff0c;并且将页面原码数据加载到该对象中2.通过调用BeautifulSoup对象中相关的…

BS架构通信原理

BS架构通信原理 1.关于域名 https://www.baidu.com/&#xff08;网址&#xff09; www.baidu.com(是一个域名) 在浏览器地址栏上输入域名&#xff0c;回车后&#xff0c;域名解析器会将域名解析出来一个具体的IP地址和端口号等。 该地址也可以通过DOS窗口来显示&#xff08;…

Python爬虫:bs4解析

Python爬虫&#xff1a;bs4解析 html语法什么是bs4bs4安装从bs4中查找数据的方法bs4的基本使用实例&#xff1a;使用bs4爬取优美图库图片思路代码 html语法 <标签 属性“值” 属性“值”>被标记内容 </标签>什么是bs4 bs4全称&#xff1a;beautifulsoup4&#xf…

合泰BS8116A-3触摸芯片开发踩坑指南

一、硬件说明 引脚图&#xff1a; 接线&#xff1a; 说明&#xff1a;由于用到了唤醒检测&#xff0c;所以KEY16引脚用作IRQ中断唤醒功能&#xff0c;未使用引脚拉低。 二、IIC配置说明 1、最大波特率&#xff1a; 实际单片机配置最好不要设置波特率100Khz容易出错&#xff…

BS4基本用法

1.找米下锅&#xff0c;安装bs4库 pip install BeautifulSoup 2.此物何用&#xff0c;BS4作用 Beautiful Soup库是解析、遍历、维护“html标签树”的功能库。在爬虫中用于解析数据。 3.bs4标签元素&#xff0c;解析其组成&#xff0c;方可庖丁解牛&#xff0c;游刃有余 by…

XPath和bs4

XPath XPath 是一门在 XML 文档中查找信息的语言。XPath 用于在 XML 文档中通过元素和属性进行导航 使用方法&#xff1a; 使用前要把response.text通过etree.HTML()转换为对应的格式&#xff0c;再通过 变量名.xpath(xpath)截取内容 responserequests.get(url,headershead…

Python爬虫 BeautifulSoup(bs4)-- bs4介绍、安装bs4、bs4基础语法

1. BeautifulSoup简介 BeautifulSoup简称&#xff1a; bs4 。什么是BeatifulSoup&#xff1f; BeautifulSoup&#xff0c;和lxml一样&#xff0c;是一个html的解析器&#xff0c;主要功能也是解析和提取数据 。优缺点&#xff1f; 缺点&#xff1a;效率没有lxml的效率高优点&a…

Python爬虫 之数据解析之bs4

数据解析之bs4 一、bs4进行数据解析二、bs4库和lxml库的安装三、BeautifulSoup对象四、项目实例 一、bs4进行数据解析 1、数据解析的原理 ① 标签定位。 ② 提取标签、标签属性中存储的数据值。 2、bs4数据解析的原理 ① 实例化一个BeautifulSoup对象&#xff0c;并且将网页源…

【数据结构】手撕顺序表

一&#xff0c;概念及结构 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构&#xff0c;一般情况下采用数组存储&#xff1b; 在数组上完成数据的增删查改。 1&#xff0c; 静态顺序表&#xff1a;使用定长数组存储元素。 2.&#xff0c;动态顺序表&#xff1…

java bs项目_BS(Java平台)

采用前后端分离的体系架构。采用前后端分离的开发模式的好处是前端、后台互不影响,发挥各自的特长,提高工作效率。前后端根据约定好的接口规范,按照规范的报文格式分别进行独立开发。前后端开发完成后,进行前后端联调,联调过程中对前后端的参数传递,页面串联,业务逻辑等…

BS架构和CS架构的优缺点

1、CS、BS架构定义 CS(Client/Server):客户端----服务器结构。C/S结构在技术上很成熟,它的主要特点是交互性强、具有安全的存取模式、网络通信量低、响应速度快、利于处理大量数据。因为客户端要负责绝大多数的业务逻辑和UI展示,又称为胖客户端。它充分利用两端硬件,将任…

HAproxy+keepalived高可用配置搭建

目录 一、概述 &#xff08;一&#xff09;简介 &#xff08;二&#xff09;核心功能 &#xff08;三&#xff09;关键特性 &#xff08;四&#xff09;应用场景 二、安装 1&#xff09;拓补图 2&#xff09;配置 &#xff08;一&#xff09;内核配置 &#xff08;二…

oracle orcl不存在,oracle服务丢失的处理方法之OracleServiceORCL不存在示例

oracle服务是oracle数据库的重要组成部分,下面就教您oracle服务丢失的处理方法,如果您之前遇到过oracle服务丢失的问题,不妨一看。 今天发现数据库服务器上的所有oracle服务都丢失了——也就是说在服务管理器中没有oracle服务了,如OracleOraDb10g_home1TNSListener、Oracle…

如何打开计算机的Oracle服务,win10系统手动启动oracle服务的操作方法

有关win10系统手动启动oracle服务的操作方法想必大家有所耳闻。但是能够对win10系统手动启动oracle服务进行实际操作的人却不多。其实解决win10系统手动启动oracle服务的问题也不是难事&#xff0c;小编这里提示两点&#xff1a;1、打开“服务”窗口。或者“管理”口&#xff1…

在现有oracle服务器上新建一个oracle实例

一 概述 假如一台服务器上已经安装了一个单机版的oracle实例orcl&#xff0c;这时想在这台服务器上再部署一个单机版的oracle实例ystat&#xff0c;则可以参考该文档进行部署。 注意&#xff1a;新实例名不要带特殊字符&#xff0c;下划线也不要。 二 操作步骤 2.1 创建相关…

linux下Oracle服务的启动和关闭

1.前言 确保我们能够访问oracle数据库包含两部分&#xff0c;一个是oracle实例&#xff0c;一个是监听&#xff0c;两个同时开启&#xff0c;我们才能正常的使用数据库&#xff0c;因此我们在关闭和启动oracle服务时&#xff0c;也需要同时操作实例和监听。能够操作linux的工具…