BootLoader

BootLoader的概念

BootLoader就是在操作系统内核运行之前运行的一段小程序。通过这段小程序,可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境,这就是所谓的引导加载程序(Boot Loader)。

在Flash存储中存放文件的分布图如下所示:

归根结底,BootLoader的任务是引导操作系统,所谓引导操作系统,就是启动内核,把内核加载到内存RAM中去运行。

本文中,BootLoader的起始地址为0x20000000,内核(uImage)的起始地址为0x20008000,根文件系统(initrd.img.gz)的起始地址为0x21000000

BootLoader的分类

通常,BootLoader是严重地依赖于硬件而实现的,特别是在嵌入式中。因此,在嵌入式里建立一个通用的BootLoader几乎是不可能的。因此,BootLoader的种类繁多,比如:

可以看出,不同的bootloader具有不同的使用范围。

其中最令人瞩目的就是有一个叫U-Boot的BootLoader,是一个比较通用的引导程序,而且同时支持X86、ARM和PowerPC等多种处理器架构。

U-Boot

U-Boot,全称 Universal Boot Loader,是遵循GPL条款的开放源码项目,是由德国DENX小组开发的用于多种嵌入式CPU的BootLoader程序,对于Linux的开发,德国的u-boot做出了巨大的贡献,而且是开源的。

U-Boot具有以下特点:

  1. 开放源码;
  2. 支持多种嵌入式操作系统内核,如Linux、NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS;
  3. 支持多个处理器系列,如PowerPC、ARM、x86、MIPS、XScale;
  4. 较高的可靠性和稳定性;
  5. 高度灵活的功能设置,适合U-Boot调试、操作系统不同引导要求、产品发布等;
  6. 丰富的设备驱动源码,如串口、以太网、SDRAM、FLASH、LCD、NVRAM、EEPROM、RTC、键盘等;
  7. 较为丰富的开发调试文档与强大的网络技术支持;

其实,把u-boot可以理解为是一个小型的操作系统。

U-Boot的常用命令

U-Boot的文件通过SD卡或者USB线可直接烧写到Flash中,然后就可以进行U-Boot的命令的执行了。

U-Boot的基本命令

  • print:打印U-Boot中的环境变量(打印格式:变量名=变量值)
  • setenv:设置U-Boot中的环境变量,重启后无效(设置格式:setenv 变量名 变量值;当变量值为空的时候,表示删除该环境变量)
  • saveenv:保存U-Boot中的环境变量,重启后有效
  • md:内存显示,显示特定内存地址的内容(设置格式:md 内存地址,如20008000)

U-Boot网络层相关命令

一般而言,将文件(例如:内核)从主板传输到目标板采用TFTP协议,这就涉及到U-Boot的网络层设置。而U-Boot的网络层的设置与环境变量ipaddr有关:

setenv ipaddr 192.168.10.3
saveenv

需要注意的是,该ip地址需要和虚拟机的网卡地址在同一网段,即需要Ping通(U-Boot为了精简,Ping协议并不完全,必须由目标板去Ping主机虚拟机)。这样才能完成目标板与主板虚拟机的网络层的通畅。

Ping通之后,就可以通过TFTP进行文件传输了。由于U-Boot内有TFTP的客户端,因此服务器端有两种可能:

  • 主板:下载TFTPD软件,设置目录并选择网卡
  • 主板虚拟机:下载服务器端软件,命令如下:
sudo apt-get install tftpd-hpa       //32位
sudo apt-get install tftpd openbsc-xinetd   //64位

然后TFTP的目录配置文件在/etc/inetd.conf中,比如:

sudo vi /etc/inetd.conf
...
tftp dgram udp wait noboby /usr/sbin/tcpd /usr/sbin/in.tftpd [目录]
...
sudo /etc/init.d/tftpd-hpa/restart      //重启服务

目标板进行TFTP需要知晓服务器端的ip地址、端口号、传输到的内存地址和需要传输的内容。服务器端的ip地址在环境变量serverip,端口号是TFTP规定好的(69号端口),剩下的两个参数就是tftp命令需要指定的:

tftp 20008000 hello.c

这段命令的意思为,从环境变量serverip的服务器端将hello.c文件通过TFTP协议传输到目标板内存地址为20008000的内存中。

U-Boot Flash相关命令

当调试完程序后,最终需要将其写入NandFlash中,否则程序仍在内存中,一旦重启就会消失。这就需要用到nand命令了。其一般格式为:

nand erase [NandFlash内部地址] [擦除大小]
nand [write/read] [内存地址] [NandFlash内部地址] [搬移大小]

通常,在使用write之前都需要先进行erase命令。例如:

nand erase 500000 1024           //擦除Flash5M地址1字节的内容
nand write 20008000 500000 1024         //将内存20008000以后1字节的内容写入Flash5M地址
nand read 20008000 500000 1024          //将Flash5M地址以后1字节的内容读取到内存20008000

这样就能保证,目标板重启之后数据也不会丢失了。

U-Boot启动内核命令

bootm命令用于启动一个操作系统映像。它会从内核映像文件(uImage)的头部取得一些信息,这些信息包括:映像文件的基于的cpu架构、其操作系统类型、映像的类型、压缩方式、映像文件在内存中的加载地址、映像文件运行的入口地址、映像文件名等。

紧接着bootm命令将映像加载到指定的地址,如果需要的话,还会解压映像并传递必要有参数给内核,最后跳到入口地址进入内核。

U-Boot启动内核,需要满足一定的条件:

  • 启动参数 bootargs
  • 根文件系统

启动参数bootargs,一般包括以下三项:

  1. root=:启动的根文件系统的位置相关信息
  2. init=:内核启动后的第一个可执行文件,即init进程
  3. console=:内核启动后,作为控制台的设备

根文件系统一般有两种方式:RamdiskNFS

Ramdisk:顾名思义内存磁盘,即将根文件系统放在内存中。本质上,RamDisk并非一个实际的文件系统,而是一种将实际的文件系统装入内存的机制,并且可以作为根文件系统。实际上它使用的文件系统是ext2。

此时的配置需要指定root的位置在RAM,同时还需要指定RAM中的具体位置大小,启动参数为:

setenv bootargs root=/dev/ram initrd=0x21000000,8M init=/linuxrc console=ttySAC0,115200
saveenv

确定完启动参数之后,就可以传输文件,并进行内核启动了,使用bootm命令:

tftp 20008000 uImage
tftp 21000000 initrd.img.gz
bootm 20008000

NFS:顾名思义网络文件系统。即允许网络中的计算机之间通过TCP/IP网络共享资源。在NFS的应用中,本地NFS的客户端应用可以透明地读写位于远端NFS服务器上的文件,就像访问本地文件一样。这种方式,对于调试就非常方便

简单一点说,就是将根文件系统放在主板的虚拟机上,目标板通过NFS来进行访问。那么,显而易见,主板的虚拟机需要安装NFS的服务器端。

sudo apt-cache search nfs-               //记不得名称了可以用此命令搜索
sudo apt-get install nfs-kernel-server

安装完成后,需要进行NFS的配置,配置文件在/etc/exports中:

sudo vi /etc/exports
...
[目录] *(rw,sync,no_subtree_check)
...
sudo /etc/init.d/nfs-kernel-server restart      //重启服务

需要注意的是,根文件系统的后缀为.gz,是一个压缩包。当通过TFTP传输给目标板之后,目标板会自动对其进行解压操作,形成相应的文件夹。然而,如果采用NFS的方式,服务器端需要自身解压完,留给目标板进行访问:

gunzip initrd.img.gz         //解压为initrd.img,相当于一个ios文件
mount -t ext2 init.img [挂载目录]               //挂载initrd.img

服务器端配置完成后,目标板的配置需要指定root的位置在NFS,同时还需要指定NFS中的具体ip端口目录绝对地址,端口号是NFS规定好的。

除此之外,U-Boot一旦启动内核之后,它就丧失了对目标板的主动权,此时它的环境变量ipaddr也丧失作用了。这个时候,目标板就是属于无ip的状态,自然NFS就无法连接上了。因此,还需要设置ip参数。启动参数为:

setenv bootargs root=/dev/nfs nfsroot=192.168.10.110:/home/rocky/work/rootfs ip=192.168.10.120 init=/linuxrc console=ttySAC0,115200
saveenv

确定完启动参数之后,就可以传输文件,并进行内核启动了,使用bootm命令:

tftp 20008000 uImage
bootm 20008000

采用NFS方式的好处就是,可以在主板虚拟机上写一个程序,并运用交叉编译器进行编译,编译完成后,自动就会同步到目标板上。这个时候,就可以直接在目标板上运行编译完的程序。即主板虚拟机编译,目标板运行

U-Boot自动启动内核命令

可以看出,上面的两种启动内核的方式都不能做到一上电就自动启动内核的作用。其实这都和U-Boot的环境变量有关:bootdelaybootcmd前者为启动后倒计时,后者为倒计时后自动执行的命令

就可以将内核、根文件系统都nand到Flash中,倒计时后从Flash中读取并启动内核:

setenv bootdelay 2
setenv bootcmd nand read 20008000 100000 200000;nand read 21000000 5600000 400000;bootm 20008000

【Linux】嵌入式Linux系统的移植(下篇:BootLoader,以U-Boot为例)相关推荐

  1. ina3221嵌入式linux,嵌入式Linux之我行——Linux-2.6.30.4在2440上的移植之文件系统

    嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤.一为总结经验,二希望能给想入门嵌入式Linux的朋友提供方便.如有错误之处,谢请指正. 一.移植环境 主  机:VMWa ...

  2. linux进程自动启动,linux 嵌入式 自启动 系统自动登录-自动启动程序或脚本

    linux嵌入式开发板,设置系统自动登录和自动运行脚本或程序,下面一一进行说明. 一.系统自动登录 1.1.在实验板添加logintest脚本 logintest脚本位置:/home/root/    ...

  3. 能装linux的嵌入式,试试一张软盘可装下Linux(嵌入式Linux)

    嵌入式Linux由一个几百KB的kernel(内核)和一些根据需要进行定制的系统模块组成.由于Linux是开放源代 码的操作系统,因此,其在嵌入式领域有其不可替代的成本和高度灵活性等优势. 将Linu ...

  4. 嵌入式硬件Linux,嵌入式linux硬件什么要求

    大部分使用者初次接触linux系统电脑时,都不知道电脑里面的硬件到底是什么,和外设硬件又是什么.为此学习啦小编为大家整理推荐了相关的知识,希望大家喜欢. 嵌入式linux硬件要求的详细说明 lscpu ...

  5. lcd命令 linux,嵌入式Linux裸机开发(十五)——LCD

    嵌入式Linux裸机开发(十五)--LCD 一.LCD简介 LCD(Liquid Crystal Display)是液晶显示器简称.LCD的构造是在两片平行的玻璃基板当中放置液晶盒,下基板玻璃上设置T ...

  6. linux -- 嵌入式2.6.37wifi-vnt6656移植驱动

    [A]          2.6.32.2内核下的移植 这里是友善之臂提供的2.6.32.2内核 + VNT6656 WLAN源代码 1.20.03的编译和使用方法: 1.编译驱动模块 目前1.20. ...

  7. ndis拨号软件 linux,嵌入式linux系统下NDIS拨号

    一.USB端口信息 U8300C模块USB会枚举出6个逻辑端口,他们的枚举顺序.端口功能.端口名称如下表所示: 二.驱动集成 1.内核配置: make menuconfig 到内核时: Device ...

  8. 嵌入式面试linux,嵌入式Linux面试题

    1. 把N个有序链表合并成一个新的有序链表 2. 派生类的构造函数/析构函数调用次序(常见) 3. 列举常见的设计模式(Marvell) 4. 解释黑盒测试与白盒测试,谈谈你项目中如何做测试 5. 设 ...

  9. linux -- 嵌入式linux下wifi无线网卡驱动

    插入模块驱动 [root@WEIYAN wifi]$ insmod zd1211rw.ko usb 1-1: reset full speed USB device using s3c2410-ohc ...

  10. 嵌入式Linux系统开发笔记(七)

    嵌入式Linux系统开发笔记(七) 七.U-Boot基础 1.概述 在移植 Linux之前我们需要先移植一个 bootloader 代码,这个 bootloader 代码用于启动 Linux 内核, ...

最新文章

  1. linux -- chcp
  2. 微信公众平台开发(26) ACCESS TOKEN
  3. PHP怎么读写XML?(四种方法)
  4. 5.2k Star!一款 Python 实现的美观终端资源监视器
  5. 关于 eclipse 插件JsonEditorPlugin-0.9.4安装与使用
  6. spring处理循环依赖时序图_Maven依赖管理系统
  7. 使用GY89的BMP180模块获取温度和压强(海拔)
  8. postgresql-int,bigint,numeric效率测试
  9. 命令查询每个文件文件数
  10. 机器学习和深度学习资源汇总(陆续更新)
  11. 下方点击出项上方对应的插件_sketch必备插件Craft功能详解(下)
  12. 字节、快手、天弘基金等 :量化/算法工程师岗位【社招|校招|实习生】
  13. (二)SDRAM——SDRAM操作时序
  14. TM4C KEIL模板建立
  15. Java求1000以内的水仙花数
  16. 家里光猫用管理员权限登录
  17. 问题记录vips.h:133: undefined reference to `vips_reduce‘ collect2: error: ld returned 1 exit status
  18. [CERC2014] Outer space invaders
  19. 美团外卖API接入(一)
  20. Centos7 防火墙配置

热门文章

  1. 【连接池】Tomcat 连接池中 maxActive,maxWait,maxAge,testOnBorrow,testWhileIdle等选项的作用
  2. ShowDoc在线API文档、技术文档工具
  3. Shiro权限控制+整合shiro
  4. jq实现点击容器实现2张图片切换(改变src路径)
  5. Java 泛型类、泛型方法和泛型接口
  6. 直接插入法(java实现)
  7. C/C++面试感受和经验以及面试题收藏
  8. Java 9 与 Java 10
  9. Apache/.htaccess的Order Allow,Deny 详解
  10. CarSim与多版本MATLAB联合仿真问题