uboot的学习前传



为什么要有uboot

uboot主要作用是启动操作系统内核的。

uboot还要负责部署整个计算机系统。

uboot中还要有操作flash等板子上的硬件驱动

uboot还得提供一个命令行让我们可以在命令行下可以进行操作


uboot就是干以上或者更多事情的一个裸机程序而已。



计算机系统组成的三个重要部件: CPU + 外部存储器(flash/硬盘) + 内部存储器(内存, DDR/SDRAM/SRAM)



PC机的启动过程:

在静态时,BIOS程序放在norflash中,在PC机的主板上,OS放在外部存储设备中,掉电时CPU是不工作的,掉电时内存也是无作用的。

在上电开始时,norflash中的bios程序,先开始运行,因为norflash中的程序上电是可以直接运行的,这部分程序将DDR等内存进行初始化,将外部存储设备也进行初始化,并且把外部存储设备中的OS复制到DDR中去,然后从norflash中跳转到DDR中去运行OS。直到启动OS。(OS启动后BIOS就无用了)


典型的嵌入式Linux系统的启动过程

典型嵌入式系统的部署情况:uboot(也就是botterloder)放在flash等外部存储设备中(能作为启动设备的FLASH,就是说如果你的uboot是否放在SD卡中的,那么你的CPU要能够支持SD卡的启动)。OS也放在flash中,因为嵌入式设备是没有硬盘的,硬盘可能太大了,所以也是放在了flash中,可以把flash当做嵌入式设备的硬盘。内存也是掉电时无作用的,现在的内存多是DDR的,CPU掉电时也是不工作的。

启动过程:

先执行uboot(在210中是irom中固话的代码先去初始化flash,在从flash中读取uboot的前16KB字节到sram中去运行),所以uboot的代码就是初始化DDR,将OS读取到DDR中,然后跳转到DDR中去运行OS,直到OS启动完毕(uboot就无用了,OS启动好后)。

总结:所以可以看出来,PC机的启动过程和嵌入式系统的启动过程其实都是一样的,只是BIOS变成uboot,硬盘变成了flash


Android的启动过程

Android的启动过程和linux系统(典型的嵌入式设备)的启动过程几乎是一样,OS启动之前是完全一样的,只是在操作系统的内核启动后,加载根文件系统后不同了。

可以认为启动过程分为两个阶段:第一个阶段就是uboot到OS启动;第二个阶段就是OS启动后到rootfs(根文件系统)加载到命令行执行;Android的启动和linux的启动的差别在于第二阶段。




现在默认的芯片都支持uboot启动。uboot就是一个程序,一个网上的开源项目。


uboot具有可移植性的意思并不是说,我们拿到uboot代码后直接下载到我们开发板上就可以使用,而是说uboot源代码具有通用性,我们很多的开发板都可以用到uboot的源代码,在uboot源代码的基础上,我们可以进行移植,并且供我们的开发板去使用。




uboot必须解决的一些问题

1、uboot必须自身开机直接启动:uboot要能启动,必须放在SOC能支持的启动介质中才可以,并且uboot必须对相应的硬件进行代码的修改和移植才可以,这些代码都在uboot的第一阶段的start.S中处理的,什么重定位呀,什么初始化内存呀,什么什么的。

2、uboot要能够引导操作系统内核的启动,并且给内核传参。

uboot的终极目标就是要启动操作系统内核。

内核传参是说,linux内核在设计的时候,是设计成可以被传参的,我们的可以在uboot中事先给linux内核一些特定的参数,我们把这些参数放在了内存的特定位置然后传参给linux内核,linux内核启动后会到这个内存的特点位置读取到uboot传进来的参数,然后再linux内核中去解析这些参数,这些参数将被用来指导我们linux内核的启动过程。

3、uboot要能提供系统的部署功能

uboot必须能够被人使用借用之后,我们完成了整个系统(uboot、kernel、rootfs)在flash上的烧录下载工作。

以前我们在裸机中,就是利用uboot,我们的uboot可以放在SD卡中,因为210支持SD卡的启动,完了之后在uboot的命令行下,使用uboot的fastboot这个功能,将我们的uboot,kernel,rootfs等各种镜像烧录到我们开发板的iNand中,然后从iNand启动。

4、uboot要能进行SOC级和板级的硬件管理

SOC级就是SOC的内部外设,譬如(串口,LCD控制器等)要对这些硬件能进行驱动,因为我们在使用uboot的时候会有一个通过串口给我们一个显示界面,可以让我们进行人机交互,还有我们烧机的过程中,我们开发板的lcd显示屏上也会显示进度条,所以我们uboot中的内容还要包含一些对硬件的驱动。板级指的就是我们SOC外面的那些硬件我们也要能进行管理,不然的话我们怎么将我要烧录的镜像烧录到iNand中。让iNand等就在SOC外面的就是我们板级硬件。

5、uboot的生命周期:

uboot什么时候开始运行,什么时候结束运行。uboot是一个裸机程序。它不是一个操作系统,uboot是一个单线程的,它最终沉浸于一个死循环中,所以我们用uboot 跟主机进行ping的时候,我们可以在uboot中用ping的命令,主机收到后,主机发包,这样我们uboot能接收到,就ping通了,但是我们如果用主机直接pinguboot的时候,是不行的,因为如果我们用主机直接给uboot发包,我们uboot是不理会的,因为这个时候uboot并没有接收到命令,因为uboot是单线程的,它还沉浸在自己的死循环中呢,这部分内容我现在理解的还浅,等到学到ping的时候,应该会理解的比较深刻。

uboot因为是一个裸机程序,所以这也决定了他的生命周期,uboot一旦运行的话,就会只运行uboot,不会运行其他的程序,OS一运行的时候,uboot就将会停止运行,uboot无法在运行了。(OS运行时,uboot就死掉了)如果还想见到uboot我们只能重启系统,但是这时我们见到的uboot是uboot的另一生了。相当于uboot重新在我们外部存储设备中加载到内存中运行了一遍。

6、uboot的入口和出口

uboot的入口就是开机自动启动。如果CPU我们用的是SD卡启动,那么uboot的入口就是SD卡中,从SD卡中把uboot加载到内存中运行。如果CPU我们用的是iNand启动,那么就会在iNand中把uboot加载到内存中去运行。

uboot的唯一出口就是启动内核,它如果没有启动内核的话,uboot将会一直被运行,如果它启动了内核的话,那么uboot就死了。

uboot的工作方式:

从裸机镜像uboot.bin说起: uboot的本质就是一个裸机程序。uboot.bin文件,在程序没有运行的时候,uboot.bin就好好的躺在启动介质中,当我们程序开始运行时,uboot.bin中的程序就会加载到内存中一条一条的指令进行运行。

uboot程序实现了一个shell界面。shell不是操作系统,虽然它和linux中的终端的工作方式一样,但它不是操作系统,操作系统可以有shell界面,uboot也可以有shell界面,我们之前在裸机中也自己写过一个简单的shell

环境变量:环境变量就是系统的全局变量,我们可以通过环境变量来改变程序的运行结果,而不用编译运行的操作。程序在运行时会读取环境变量的值来做出相应的动作,我们可以通过环境变量来指导程序的运行。




uboot中的常用命令

uboot中的命令有些是可以简化的,像printenv可以简化成print 打印环境变量

setenv可以简化成set 设置环境变量。

有些命令会带参数(格式是固定的)第一个空格之前是命令,第一个空格之后的是参数,接着每隔一个空格就是一个参数,有些命令可以带参数也可以不带参数,如help命令,当我们不知道一个命令的名字的时候可以在uboot中shell下输入help即可查询。当我们想要一个命令的具体用法时,可以help +这个命令的名字。

命令行中的特殊符号(单引号)

有些命令带的参数比较长,可能带的参数中也会存在一些空格,会误导我们的uboot中的程序去解析我们的命令,所以如果我们的命令如果带的参数会存在空格的话,我们就要用单引号将我们的这个参数给引起来。

有些命令是一个命令族:意思就是命令是一样的但是后面的参数不一样,例如movi命令,就是和moviNand有关的,只在三星移植过的uboot中会有可能

uboot的第一个常用命令:print/printenv

不带参数的命令,用来打印环境变量的,环境变量就是uboot中的全局变量,不同的是环境变量可以保存在flash中,当我们这次设置好了一个环境变量的值后,可以将环境变量保存在flash中,下次程序在加载到内存中运行的时候,这个环境变量的值就是我们上次设置好的了,而全局变量是放在内存中的数据段的,是不可能被保存住的。当程序运行结束的时候,全局变量就死掉了。无法保存

在flash中,uboot放在flash的开始的那一块分区中,接着环境变量又在flash中划分了一个分区放环境变量,这个分区是紧接着uboot的。接着又在uboot的分区后面划分了一个分区放操作系统内核OS,接着OS分区后面又在flash中划分了一个分区放rootfs根文件系统。

在启动的时候,从flash中的uboot想办法将uboot放在DDR开始的地方去运行,同时也会将flash中跟uboot相关的环境变量读取到DDR中环境变量区域(我们划分的),只读取一次,从flash中的环境变量读取到DDR中,放在uboot运行内存空间的后面。所以我们在flash中的环境变量分区中,我们的bootdelay这个环境变量是我们原先的值,比如3,当我们将这个环境变量读取到内存中DDR中运行的时候,我们在uboot在DDR中运行的时候,通过uboot的shell界面的setenv这个命令,setenv bootdelay 10将bootdelay这个环境变量的值改成了10,改的只是内存中的bootdelay那一份,并没有改变flash中的bootdelay那一份环境变量,并且因为内存是掉电就不会保存上一次的东西的,所以我们要将在内存中改变的那一份环境变量保存在flash中,才可以在下一次启动的时候,这个环境变量的值真正的被我们改变了,所以我要在uboot的shell界面中用saveenv这个命令,保存我们设置的环境变量的值,将在内存中的那一份环境变量的值保存到我们flash中,这样下次再启动的时候,就可以是我们设置的环境变量的值了。


uboot中的第二个常用命令:setenv/set

设置环境变量,带参数的,setenv 环境变量的名字 环境变量要设置的值

uboot中的第三个常用命令:save/saveenv

不带参数的命令,直接将我们内存中的环境变量的值,同步保存到我们flash中的环境变量。注意:环境变量的保存是整体的覆盖保存。就是说,我们save后会将内存的中的环境变量整体保存覆盖到我们flash中的环境变量分区的环境变量。这是因为我们的flash设备是块设备,写入和读取字节的时候,只能是一块一块的,所以我们保存一个环境变量到我们flash中,和保存一块环境变量到我们flash中,成本都是一样的。

uboot中的第四个常用命令:网络测试命令 ping

命令的用法就是 ping ip地址

ping的时候要注意:

1、首先要用网线将主机window的网口和开发板上的网口连接起来

2、设置的IP地址是我们主机Windows的有线IP地址(本地地址),而不是无线IP地址,因为我们板子和主机是用网线进行连接的。打开网络中心,找到更改适配器设置。设置我们window本地连接的IPV4,点击里面的使用一下IP地址,不是自动获取(因为我们一般上网用的是自动获取),一般设置为 192.168.1.10(或者20或者30都行),点子网掩码,会自动出来。剩下的就不用管了。网关是用来上外网的,我们暂时是用局域网来玩,DNS服务器也是用来上外网用的,暂时不用管。

3、这时候不一定能ping通,我们要确认开发板中的uboot中的里的几个网络相关的环境变量的值对不对。

ethaddr这个环境变量是网卡的地址,这个是随便设的,没有关系

netmask这个环境变量的值是子网掩码,是有影响的。但是一般都不会错,都是255.255.255.0

ipaddr这个环境变量的值是最重要最重要的,这个环境变量的值表示当前开发板的IP地址。这个地址必须要和我们Windows中的IP地址在同一个网段。同一个网段的意思就是说,一个IP地址,如192.168.1.10 其中前三个的数必须是相同的。

所以我们发现,我们通过uboot中打印ipaddr这个环境变量的值,发现这个值的网段和我们主机的网段不在同一个网段上,所以我们要将我们开发板的IP地址的网段设置成跟我们主机的IP地址的网段一样,也就是前三部分要一样的,但是第四部分要不一样,因为第四部分一个是我们主机的地址,一个我们开发板的地址,在同一个网段下,地址是不能相同,主机地址是10了,那么我们的开发板的地址就不是10了。

网段的概念:一个IP地址分为两个部分,一个网段,一个是网段内的主机地址,前三个数字则表示网段,后一个数字则表示网段内的主机地址。(由我们的子网掩码来区分,哪一部分是网段地址,哪一部分是IP地址),在我们的子网掩码中,如果子网掩码是255.255.255.0的情况下,我们192.168.1.10 的IP地址,前三部分表示网段地址。第四部分表示我们主机地址。

开发板和主机的ping通:

开发板运行linux的情况下和主机Windows的ping通

开发板运行linux的情况下和虚拟机Ubuntu的ping通

开发板运行uboot的情况下和主机Windows的ping通

开发板运行uboot的情况下和虚拟局Ubuntu的ping通

1、开发板运行linux的情况下和主机Windows的ping通

(1)先将开发板刷机成linux+qt的镜像,然后启动进入linux命令行的终端底下

(2)在linux命令行底下使用ifconfig命令将开发板中的IP地址设置成和我们主机的IP地址同一个网段(我们默认就将主机的IP地址设置为192.168.1.10,开发板的uboot或者linux的IP地址设置为192.168.1.20,虚拟机Ubuntu的IP地址设置为192.168.1.141)

运行启动后,在linux的命令行下,输入ifconfig查一下 eth0的IP地址是不是,如果不是的话我们设置成我们自己默认的值192.168.1.20,用ifconfig eth0 192.168.1.20设置,设置完了之后我们在ifconfig去查询一下eth0看是否设置好了,之后就可以ping通了。

2、开发板运行linux的情况下和虚拟机Ubuntu的ping通

首先要知道NAT和桥接:桥接就是外部网络能看到我们Windows主机和虚拟机Ubuntu的网络都是独立的,能看见两台设备。

而NAT呢,外部网络只能看到主机Windows看不到我们虚拟机Ubuntu,我们虚拟机Ubuntu要想和外界网络通信只能通过Windows主机的网络进行通信,相当于虚拟机的网络是在Windows的肚子中的,这是虚拟机是蹭了Windows的网。

所以虚拟机要想和我们的开发板进行网络通信,只能进行桥接进行连接。不然的话如果用NAT,是相当于一台设备的,对于网络来说。

虚拟机要想和我们的开发板ping通,进行网络通信,步骤如下,一定要记住:

第一步:虚拟机中要设置成桥接的方式,在虚拟机的设置中找到那个网络修改的地方,选择桥接的方式即可。

第二部:我们虚拟机的编辑中,有一个虚拟网络编辑器,这里面要设置成桥接到有线网卡,因为我们用的就是有线的ping,进行网络通信。默认的这个值是自动(因为我们一般的电脑中都有两个网卡,一个是有线网卡,一个是无线网卡,如果是自动的话,那么一般的情况会影响到我们的ping通,因为自动的话会默认的去将我们的虚拟机桥接到无线网卡上,而我们的开发板和我们的主机是通过有线进行连接的,所以是不可以的),不可以,我们要进行设置,设置成ETH那个,完了点应用,点确定就好了。

第三步:在我们的虚拟机Ubuntu中将IP地址设置成192.168.1.141,这是我们的虚拟机Ubuntu中的网卡IP地址。这是我们自己默认的值(可以直接通过/etc/network/interfaces文件设置成静态的,也可以直接在命令行下通过ifconfig去设置),设置好了以后在重启网卡,在14.04版本的Ubuntu中先在命令行下输入ifconfig eth0 down 在输入ifconfig eth0 up 就可以重启网卡了,要切换到root用户才可以。

此时我们在开发板linux下输入ping命令,ping虚拟机的IP地址就可以ping通了,在虚拟机Ubuntu的命令行下输入ping命令,ping我们开发板的IP地址,也是可以ping通的,这时两者就可以通过网络进行通信了,局域网



3、开发板运行uboot的情况下和主机Windows的ping通

目前的情况在这种状态下ping不通,可能是uboot本身的网卡驱动有些问题

4、开发板运行uboot的情况下和虚拟局Ubuntu的ping通

这种情况是可以ping通的,跟运行在linux下ping通Ubuntu的方式一样,见上面的2,这个只不过是运行在uboot的情况去ping通,方法见上面的2。

开发板运行在uboot的情况下可以ping通Ubuntu,同时Ubuntu也可以ping通开发板运行在uboot的情况下。两者之间可以进行局域网通信了。

uboot中的第五个常用命令:tftp


1、tftp下载指令:tftp

uboot的任务就是启动内核,为了完成启动内核,则必须对内核进行部署,uboot为了能够部署内核,就需要能够从主机中将内核镜像下载过来,烧录到flash中,主流的方式就是fastboot和tftp(网络下载)。

fastboot的方式是通过usb进行数据传输的。我们需要在主机中装好我们的usb转串口的驱动,在uboot中输入fastboot的命令启动fastboot,之后在主机的CMD下运行fastboot.exe这个程序进行下载我们的镜像到我们的flash中,部署我们的内核。

tftp的方式是通过网络传输的的,有线网络的传输。

2、tftp下载时,实际上uboot扮演的是tftp客户端程序的角色,也就是说,我们的镜像文件会放在我们主机Windows中或者Ubuntu的tftp服务器中,放在tftp服务器的下载目录下,我们的开发板运行在uboot中,在uboot中我们使用tftp的命令去我们ping通的主机的tftp服务器中的下载目录下载即可。

但是我们要先给我们的主机虚拟机搭建起来tftp环境,搭建tftp服务器,这个就要看老师的那个嵌入式搭建tftp.pdf

文档了,后续在做,现在没有网,因为需要在网上下载软件才可以。(不过还好,我可以用老师的虚拟机)

如果搭建好了,在下载之前还要检查我们uboot中的环境变量serverIP的值是否为虚拟机Ubuntu中IP地址,如果不是要设置。(serverIP的意思就是我们主机虚拟机中的tftp服务器的IP地址)之后

则可以在uboot下输入 tftp 加内存地址(0x30000000) 加要下载的镜像(zImage-qt)

这时就将我们的镜像下载到了我们开发板的DDR中了,注意是直接下载到了内存了。因为我们在uboot下输入tftp命令下载时,下载的镜像就是下载到了我们设定的那个内存地址中去了 

gatewaip是网关地址,不知道有没有用,但最好也进行设置,一般设置的值是网段要和我们主机的一样,最后一部分是.1


uboot中的第五个常用命令:nfs(那就不能叫做常用命令了)

老师没有讲,老师说这个命令在uboot中也是有的,他没有研究过,我可以通过网络信息进行学习,不过现在没网

uboot中的第六个常用命令:

1、SD/iNand操作指令 :movi

开发板如果使用SD/EMMC/iNand等作为了flash,那么我们在uboot中就会使用movi命令去操作flash,或者用mmc命令。

使用方法可以使用help movi 去查找,在uboot下。可以知道movi命令是一个命令集。

movi write 和movi read 是一组,movi write 是从DDR中将内容写到iNand中,movi read 是从iNand中读取到DDR中。

movi read  {u-boot | kernel} {addr} - Read data from sd/mmc

movi read 是命令格式是不会变的,后面的{}括起来的是你参数,如果{}里面有|则表示前面和后面的两个参数只能选择一个,后面的那个{}中只有一个参数,则表示这个参数是必选的。

movi read  rootfs {addr} [bytes(hex)] - Read rootfs data from sd/mmc by size

movi read rootfs 是命令格式,是不会变的,后面的{}里面的表示是必须要有的参数,[]中的内容表示这个参数是可选的。

从SD卡或者iNand或者mmc等flash设备读取rootfs到内存中的多少多少地址中去。

movi read  u-boot 0x30000000 意思就是将iNand中的u-boot分区读取到DDR的0x30000000地址中去。

uboot代码中将iNand分成了很多个分区,每个分区都有他的地址范围,和分区名,u-boot就是放uboot的分区名。

注意:uboot命令行中,不管你输入的是什么数字,都会当做十六进制去进行处理,不管你输入的数字带不带0x,他都是带0x的。

2、Nandflash操作指令nand

理解方法方式和movi一样,自行学习

3、内存操作指令:mm、mw、md

内存DDR是没有分区的,我在使用内存时要注意不要踩到别人,我们程序员自己心里要有数。

md指令,memory display 用来显示内存中的内容

md.b 30000000 10 以字节为单位显示内存空间,10表示要显示16个字节的内存空间的内容

md.w 以2个字节为单位的显示内存空间

md.l 以四个字节为单位的显示内存空间

如果直接输入md .b 0x30000000 会一直显示

之后输入md.b 0x30000000 也会一直显示

输入md.b 0x30000000 10 就会显示一个16个字节的内存中的内容了

mw:写内存,将一个内容,写到内存中去。

mw.b 30000000 55 写一个字节的内存空间

mw.w 写两个字节的内存空间

mw.l 写四字节的内存空间

mm : 将一个块内存修改,连续字节或者连续两个字节的,或者连续四个字节的进行修改内存,输入y结束

4、启动内核的指令:bootm、go

启动内核,在uboot中表示一个指令,如果在uboot中输入一这个启动内核的命令,那么就会启动内核,不管成功了还是不成功,所以这条指令是一条死路,就相当于执行了这条指令,uboot的这一生就结束了。

bootm和go的差别:bootm指令启动内核可以给内核传参数,go指令启动内核不能给内核传参数,go命令实际上不是专为启动内核设计的,go命令其实就是一个函数指针,这个函数指针指向了一个内存地址,go命令就是跳转到那个内存地址去运行,相当于调用了这个函数指针(如:定义了一个函数指针类型的变量名为p void (*p)(void) = ((void(*)(void))(0x30000000))  我们(*p)(); 就相当于去了这个地址去运行,这就是go的实现原理)。

我们可以通过uboot将裸机程序下载到内存中的特定地址处,完了我们在uboot中使用go命令,也就是相当于函数指针,这个函数指针指向的内存地址就是我们裸机程序下载到的那个内存的地址,我直接go,就相当于调用了这个函数指针,就去了那个内存地址去运行了,可以让我们通过uboot来调试我们的裸机程序


uboot中常用的环境变量:

环境变量如何参与程序的运行:

bootdelay,开机倒计时环境变量

网络设置的环境变量:

ipaddr 是我们开发板也就是当前uboot的本地IP地址

serverIP 是我们开发板运行在uboot时,在uboot中通过tftp指令向我们的主机tftp服务器下载东西时,tftp服务器的IP地址。

gatewayip 是我们开发板也就是uboot的本地网关地址。

netmask 是子网掩码

ethaddr 是我们开发板的本地网卡的MAC地址


uboot中重要的两个常用环境变量

1、自动运行命令设置:

bootcmd=movi read kernel 30008000; bootm 30008000

setenv bootcmd 'movi read kernel 30008000; bootm 30008000'

uboot启动后,先倒数bootdelay秒后,如果没有按下回车的话,就会自动执行启动内核的命令(其实就是直接执行了bootcmd这个环境变量的值所对应的命令集(如果bootcmd在uboot中的值不是启动内核的,而是printenv的话,就开机倒数完毕后打印环境变量了))。

2、uboot给kernel传参:bootargs

在uboot中,我们将bootargs这个环境变量的值设置好,我们在bootm启动内核时,就会自动的将我们uboot中的bootargs中的参数值传递个内核。

bootargs=console=ttySAC2,115200 root=/dev/mmcblk0p2 rw init=/linuxrc rootfstype=ext3 意义解释:

console=ttySAC2,115200 控制台使用串口2,波特率115200.

root=/dev/mmcblk0p2 rw 根文件系统在SD卡端口0设备(iNand)第2分区,根文件系统是可读可写的

init=/linuxrc linux的进程1(init进程)的路径

rootfstype=ext3 根文件系统的类型是ext3

setenv bootargs 'console=ttySAC2,115200 root=/dev/mmcblk0p2 rw init=/linuxrc rootfstype=ext3'


uboot中新建、更改、删除一个环境变量的方法:

新建一个环境变量的方法:set 环境变量的名字 环境变量的值

更改一个环境变量的方法:set 环境变量的名字 环境变量的值

删除一个环境变量的方法:set 环境变量的名字

uboot中对flash和DDR的管理

uboot阶段flash的分区:

uboot必须存放在flash的起始地址处(有可能是扇区0,有可能是扇区1,这就要看我们的SOC启动设计了)。像210就是从扇区1开始启动的。 

1、uboot:uboot的分区的大小必须要能够放下整个uboot,一般设计uboot分区的大小是512KB或者1MkB,一般都不会大于512kb,在大了的空间就浪费了。

环境变量:环境变量的分区一般放在紧贴在uboot分区之后,大小一般者32KB就已经足够了。

kernel:kernel分区可以紧贴这环境变量变量的分区进行存放,一般我给这个分区的大小大概是3M到5M,

rootfs:。。。。。。。。。。。。。。。。。。。。。。都是看实际移植出来的大小进行分配。

flash的其他地方,就是自由空间了,一般在kernel启动起来后,自用分区用来挂载到我们rootfs下去使用。

2、uboot阶段DDR的分区:

DDR内存和flash的不同,是在于DDR是掉电丢失的,flash掉电可以保存的。所以DDR的分区管理是在系统运行时开始部署的。

在linux内核启动之前我们要自己进行内存的分区管理,在linux内核启动了之后,我们就可以不用对内存进行管理了,就可以交给linux内核进行管理了。