作者:围补

本来启动方式这节不是什么复杂的事儿,不过想简单的说清楚明白,还真是不知道怎么组织。毕竟文字跟有声语言表达有别。但愿简单的东西别让我讲的太复杂!

Arm板系统文件一般有三个——bootloader(uboot)、kernel(uImage)及根文件系统(rootfs)。在arm板上电后,按uboot->kernel->rootfs的顺序依次启动。由于开发板上有多种存储介质,三个文件可以放在任何可以存储的介质上,因此也就导致文件的多种启动方式。本文就来讨论,以上三个文件对应不通存放位置的不同启动配置。

一般开发板上会有flash(Nor or NAND),mmc,emmc,sd卡等。系统文件可以烧写在其中的任意一种上,因此也就对应不通的启动。在开发过程中,有时经常需要改动内核,或者修改应用程序,如果每次都修改后都重新烧写到板上的存储介质,会比较麻烦。因此,为方便调试,uImage和rootfs还可以从网络启动,即nfs启动。但uboot只能从板上介质启动。

启动过程其实是先将要启动的文件从存储位置拷贝到内存空间,再在内存中运行。因此所谓不同位置启动,也就是从不同位置拷贝而已。

下面我们以开发板启动为例,分别介绍三个文件从不同位置启动的过程方法。我使用的开发板上有emmc和两个sd卡。我们按照启动顺序,依次介绍。

首先是uboot启动。Uboot是三个系统文件中第一个启动的,对它的拷贝工作由cpu中的固件决定。固件中支持从几个位置拷贝uboot,它就能存放在几个位置上。至于每次启动具体从其中的哪里开始,硬件拨码开关决定,对应拨码在开发板手册上能查到。启动之前,先将uboot的二进制文件拷贝到对应介质。有两种不同方法烧写,如下:

1.               uboot二进制文件拷贝到emmc,是通过芯片供应商的下载工具软件烧写完成;

2.               拷贝到sd卡是在Linux下,通过dd命令完成的。

烧写完成后,将启动拨码拨到对应位置即可启动uboot。

然后介绍kernel文件(uImange)和rootfs的启动。如上所述,uImage和rootfs可以从emmc、sd卡或nfs拷贝到内核启动。具体的启动位置由uboot中的参数传递的内容决定。这些参数的内容在uboot中有写死的值,也可以在uboot启动阶段进入到命令输入界面,修改这些参数的值,来改变启动位置。(作者:围补)

进入uboot命令界面后,输入如下一段命令,修改启动参数,并重启。

setenv loadaddr 0x10800000

setenv bootargs_base 'setenv bootargsconsole=ttymxc0,115200'

setenv bootargs_mmc 'setenv bootargs${bootargs} root=/dev/mmcblk0p1 rootwait rw video=mxcfb1:dev=ldb,LDB-XGA,if=RGB666video=mxcfb0:dev=hdmi,1920x1080M@60,if=RGB24 ip=dhcp'

setenv bootcmd_mmc 'run bootargs_basebootargs_mmc;mmc dev 1;mmc read ${loadaddr} 0x800 0x2000;bootm'

setenv bootcmd 'run bootcmd_mmc'

saveenv

run bootcmd

命令输入完后,重启开发板,即可按照上述命令中设置的参数来启动系统。

下面我们来分析一下uboot阶段输入的启动参数的意义,以便读者自己修改相关内容,让板子从自己需要的位置启动。

首先介绍几个命令。是在上面看到最多的setenv命令,该命令使用来设置或删除某个环境变量的。当setenv后面只带一个参数,该参数必须为已有的变量名,输入命令回车后该变量即被删除;当setenv后面有多个参数,将把其后第一个参数作为环境变量,后面其他参数作为该变量的值或内容。

第二个要解释的命令mmc。在uboot命令界面中敲入mmc,回车,能够看到其多个用法:

Usage: 

mmc read addr blk# cnt 

mmc write addr blk# cnt 

mmc erase blk# cnt 

mmc rescan 

mmc part - lists available partition on currentmmc device 

mmc dev [dev] [part] - show or set current mmcdevice [partition] 

mmc bootpart [dev] [part] - show or set bootpartition 

mmc list - lists available devices

解释一下其中几个用法:

mmc read addr blk# cnt 用来将硬盘(emmc/sd)中的内容读取到内存中。其中addr指内存中的目标位置起始地址,blk#指被拷贝内容起始存储块的块号,cnt指要被拷贝的块数。一般每个块的大小为512byte。

mmc dev [dev] [part] - show or set current mmc device [partition] 显示或设置当前设备。命令mmc dev即为显示当前是哪个device;mmc dev #意为设置“#”为当前设备。

第三个命令saveenv是保存环境变量的意思。环境变量设置后,使用该指令保存,下次重启时会按照上次保存的设置启动,就不用再次设置了。

最后,run命令比较明显,“运行”的意思。一般加在某内容为可执行命令的变量前。

再来说明一下变量。在上述参数设置命令中,参数bootargs和bootcmd是uboot的参数,其功能和名称不能被改变,其他都是用户自定义的变量,可以改变其名称。其中bootargs代表由uboot传给内核的参数;bootcmd是uboot启动时,系统自动加载的命令序列。如果设置了启动参数后,想让系统下次自动按照本次设置的方式启动,则一定要把拷贝和启动内核的语句设置为bootcmd的值,否则下次启动无法自动加载并启动内核。(作者围补)

介绍完重要的命令及uboot环境变量后,我们再来看上面的启动参数设置命令行:

setenv loadaddr 0x10800000

setenv bootargs_base 'setenv bootargsconsole=ttymxc0,115200'

setenv bootargs_mmc 'setenv bootargs${bootargs} root=/dev/mmcblk0p1 rootwait rwvideo=mxcfb1:dev=ldb,LDB-XGA,if=RGB666video=mxcfb0:dev=hdmi,1920x1080M@60,if=RGB24 ip=dhcp'

setenv bootcmd_mmc 'run bootargs_basebootargs_mmc;mmc dev 1;mmc read ${loadaddr} 0x800 0x2000;bootm'

setenv bootcmd 'run bootcmd_mmc'

saveenv

run bootcmd

按照上面对命令和参数的讲解,做一些变量的替换之后,可以看到,此处只做了两件事,一是设置环境变量bootargs的值,二是设置bootcmd的值,并保存。其中bootargs的值传递给内核,用来初始化一些设备和启动rootfs;bootcmd的值用来启动内核,即自动加载的命令序列。(最后一句run bootcmd是启动,不再是设置命令了。)

对上述命令中,采用如此多自定义变量的原因是,有些调试工具命令行输入不能过长,因此用中间自定义变量缩短一次性输入的命令行长度。我们将不必要的自定义变量做替换掉,然后来分析其内容。

setenv bootargs console=ttymxc0,115200root=/dev/mmcblk0p1 rootwait rw video=mxcfb1:dev=ldb,LDB-XGA,if=RGB666 video=mxcfb0:dev=hdmi,1920x1080M@60,if=RGB24ip=dhcp

setenv bootcmd 'mmc dev 1;mmc read0x10800000 0x800 0x2000;bootm'

saveenv

run bootcmd

将自定义变量替代掉后,能看到,参数设置其实就是做了对两个系统环境变量赋值的工作。下面具体分析各变量值得内容。

对bootargs的赋值,对要是跟rootfs启动相关。内容是一个很大的字符串,不同项之间由空格隔开,也可以把由空格隔开的多项看做是多个参数。

第一项是console=ttymxc0,115200是选择操作台,并设置波特率。

中间几项root=/dev/mmcblk0p1 rootwait rw,是对rootfs启动位置设置root=/dev/mmcblk0p1是指从设备mmcblk0的p1分区挂载rootfs。那么mmcblk0到底是哪个设备呢?由于文件系统的挂载是在kernel启动后进行的,而内核启动后会安装linux的分配方式给现有设备分配名称,因此可对应区分设备。我使用的开发板上,emmc即为mmcblk0设备,sd安装挂载顺序依次后排。如果多个卡槽在系统启动前都插上了sd卡,系统会安装sd卡槽所在接口号依次分配设备名称号。比如,两个sd卡槽,slot2和slot3(对应总线号),只插一个sd开始,无论在哪个槽都是mmcblk1;但两个都插上sd时,在slot2中的是mmcblk1,slot3中的则是mmcblk2。Ok,至此,从哪个设备挂载rootfs已经很清楚了。后面两个参数,rw是声明启动权限,即以读写方式启动;rootwait是指等待设备/dev/mmcblk0p1设备就绪后才尝试挂载rootfs。如果没有此参数,linux内核启动时可能会在存储设备尚未就绪是就尝试挂载rootfs,此时肯定挂载失败,那么启动也就失败了。

最后的几个参数,video=mxcfb1:dev=ldb,LDB-XGA,if=RGB666video=mxcfb0:dev=hdmi,1920x1080M@60,if=RGB24 ip=dhcp,是做一些设备初始化的,主要是对视频设备和网络,对不需要视频设备的嵌入式系统可以不设置此项,ip也可以单独设置。

然后是第二个环境变量bootcmd的设置,主要跟kernel启动相关。

setenv bootcmd 'mmc dev 1;mmc read0x10800000 0x800 0x2000;bootm'

设置bootcmd内容为命令序列,用用单引号包围,命令间由分号分隔。

按照上面对mmc命令的讲解,第一个命令mmc dev 1,意思是将dev 1设置为当前设备。这里就是uImage启动(拷贝)的位置。在我使用的开发板上,dev 1指放在卡槽slot2中的sd卡。此处由于linux内核没有启动,设备名称不能按照linux分配方式确定。在我使用的开发板上,dev 2是放在卡槽slot3中的sd卡,dev3是emmc。对此句做相应修改,即可更改内核启动位置。

mmc read 0x10800000 0x800 0x2000这句大家也应该可以明白意思了,即将存储设备上从块号0x800开始的0x2000个存储块的东西拷贝到内存0x10800000开始的空间内。

bootm也是uboot命令,用于加载uboot能辨认的操作系统映像。

以上,已经讲完在uboot阶段修改启动参数,进而更改启动位置的命令的含义,读者可对应修改,是系统各文件从相应位置启动。另外nfs部分,有时间在加进入。

此处仅作个人总结,入对您有所帮助无上荣幸!——作者围补

【ARM-Linux开发】 uboot启动阶段修改启动参数方法及分析的更多相关文章

  1. uboot启动阶段修改启动参数方法及分析

    作者:围补 本来启动方式这节不是什么复杂的事儿,不过想简单的说清楚明白,还真是不知道怎么组织.毕竟文字跟有声语言表达有别.但愿简单的东西别让我讲的太复杂! Arm板系统文件一般有三个——bootloa ...

  2. 嵌入式linux开发uboot启动内核的机制(二)

    一.嵌入式系统的分区 嵌入式系统部署在Flash设备上时,对于不同SoC和Flash设备,bootloader.kernel.rootfs的分区是不同的.三星S5PV210规定启动设备的分区方案如下: ...

  3. 嵌入式linux开发uboot启动过程源码分析(一)

    一.uboot启动流程简介 与大多数BootLoader一样,uboot的启动过程分为BL1和BL2两个阶段.BL1阶段通常是开发板的配置等设备初始化代码,需要依赖依赖于SoC体系结构,通常用汇编语言 ...

  4. 在Ubuntu上建立Arm Linux 开发环境

    我使用的是友善2410的板子,以前都是用Fedora,现在家里的电脑被我转为Linux专用的了,装的是Ubuntu.但是嵌入式还是要玩的,在装载过程中也遇到一些小麻烦.在此记录一下,一来自己比较健忘, ...

  5. <WP8开发学习笔记>动态修改启动时导航的第一个页面(如登录前启动页为LoginPage,登录后变为MainPage)

    很多时候我们需要在启动程序的时候根据状态改变初始导航页面,比如程序在启动的时候判断用户是否登录, 如果未登录则跳转到LoginPage.xaml否则跳转到MainPage界面. 这时候就要分析程序的启 ...

  6. Vs2013在Linux开发中的应用(19): 启动gdb

    快乐虾 http://blog.csdn.net/lights_joy/ 欢迎转载,但请保留作者信息 1.1    载入调试引擎 因为我们无法干预VC的调试引擎载入.但能够侦听VC的调试引擎载入事件, ...

  7. 成功移植SQLite3到ARM Linux开发板

    SQLite,是一款轻型的数据库,是遵守ACID的关联式数据库管理系统,它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了 ...

  8. spring-boot 启动图标修改-启动彩蛋

    spring boot启动总会显示这样的图标,但是我想不一样 到网上找了一圈,恩,找到一个不错的,做个记录 首先我们在resource目录下面放入一个banner.txt文件,Spring Boot启 ...

  9. minigui移植到arm linux开发板上无法执行

    要保证目录下有该文件 /etc/MiniGUI.cfg 复制过程使用cp –af 强制复制

随机推荐

  1. 「Django」Django内置email发送邮件

    Django内置email发送邮件 1.首先在settings.py文件设置相关参数 STATIC_URL = '/static/' # 设置邮件域名 EMAIL_HOST = 'smtp.163.c ...

  2. Java8-Lambda-No.03

    import java.util.Comparator; import java.util.Objects; import java.util.UUID; import java.util.concu ...

  3. 为什么添加了@Aspect 还要加@Component(转)

    官方文档中有写: You may register aspect classes as regular beans in your Spring XML configuration, or autod ...

  4. django加载本地html

    django加载本地html from django.shortcuts import render from django.http import HttpResponse from django. ...

  5. [React Native] Up & Running with React Native & TypeScript

    Create a new application with Typescript: react-native init RNTypeScript --template typescript Then: ...

  6. JavaMail使用SMTP协议发送电子邮件(详解)

    Properties props = new Properties(); props.setProperty("mail.transport.protocol", "sm ...

  7. Noip2003 提高组 神经网络

    神经网络 题目背景 人工神经网络(Artificial Neural Network)是一种新兴的具有自我学习能力的计算系统,在模式识别.函数逼近及贷款风险评估等诸多领域有广泛的应用.对神经网络的研究 ...

  8. 【概率论】3-8:随机变量函数(Functions of a Random Variable)

    title: [概率论]3-8:随机变量函数(Functions of a Random Variable) categories: Mathematic Probability keywords: ...

  9. CF1168C And Reachability 【构造,dp】

    题目链接:洛谷 题目描述:给出$n$个数$a_i$,若$i<j$且$a_i & a_j>0$,则$i$到$j$连一条有向边,$q$次询问,询问从$l$开始是否能到达$r$. 数据范 ...

  10. (转)实验文档3:在kubernetes集群里集成Apollo配置中心

    使用ConfigMap管理应用配置 拆分环境 主机名 角色 ip HDSS7-11.host.com zk1.od.com(Test环境) 10.4.7.11 HDSS7-12.host.com zk ...