嵌入式Ramdisk启动



Ramdisk启动概述分析


接下来我们继续看内核启动我们刚才已经提到不仅需要启动参数,同时也需要一个文件系统的支持,下面我们就来看一下如何把文件系统在开发板上使用起来。


ram1.png


如图,我们首先要有一个这样的思维,文件系统你就可以把它认为是一个模块或者是一个执行程序(图中圆圈),然后这个执行程序通过一个接口(它可以通过nandflash的nand接口也可以通过noflash数据总线接口甚至是内存中的总线接口也有可能是通过网线)跟我们的操作系统的核心(图中四边形)把它们进行一个衔接。


也就是说我们操作系统的kemel和我们的文件系统fs它们之间通过某种形式能够互相找到对方,然后再把内部指针指到fs然后按照一定的格式去读出来,然后我们整个操作系统其实就运行起来了。


所以对于文件系统我们其实可以把它认为是内核跟用户交互的一个中介,所以说在内核启动的时候不仅要启动参数的配置同时还需要文件系统进一步的部署。所谓部署其实有很多方法,但是下面作为第一节课我先重点给大家介绍两种文件系统的烧写方法或者是部署方法,第一种是Ramdisk第二种是NFS,这两种一个是通过借助我们内存,因为我们内存现在已经是ok的,然后在内存中把我们数据介子下载进去,然后用我们的内核去指到它那里就可以。第二种就是通过我们的网线,让它利用网线的方式去直接跟我们的服务器的一个介子进行交互。


应该这样说,在我们实际开发中调试接口,就是我们开发人员在工作中,公司开发中NFS居多,因为这样对于我们开发来说很方便。但最后真正变为成品nfs肯定不现实,因为你不可能拿一台服务器挂在那里。所以说我们一般来说可能会用到Ramdisk,那么下面我们来按照Ramdisk的形式来说一下。


首先我们来说什么是Ramdisk,顾名思义就是内存磁盘,也就是把我们文件系统里面的内容在我们的ram上运行起来,然后在ram中运行起来过后,我们就直接把内核指到ram中,对于Ramdisk也是一样的,在启动参数的时候我们就要告诉内核我们是通过ram来启动的,同时还告诉ram启动的话又需要什么样的设备信息,后面其实就是一致的。


下面我们来看Ramdisk我们需要配置的一些内容,首先来说还是第一点,root=/dev/ram对于格式我们是/dev/ram,这样设置完就相当于内核已经知道了,原来我是去找根也就是说去找文件系统的设备在ram上,但是我们还有个新的问题,我只是设备知道是ram了,但ram的哪个地方是我们的文件系统呢?所以这又是个新的疑问。


ram2.png


如图,ram我们可以认为内存比较大(图中大四边形),那么在内存中肯定有一部分的内容是运行我们的数据(图中最上面的圆圈),有些可能是内核(图中中间的圆圈),还有些其他的(图中最下方的圆圈),所以我们需要把文件系统的特殊的数据放到一个特定的位置上,然后让内核在这个特定的位置上去找,或者是去挂。这样的话,我们这个文件系统才能为内核服务。


所以说关于一个“root=/dev/ram”这个符合其实对于我们Linux来说还是不满足,因为它只知道内存,内存的具体细节在哪里,也就是说我们在启动参数的设备信息就需要单独去记忆了。


那么对于ram中我们设备信息是记哪一个变量,我们来看一下,它的名字比较好记是一个缩写“initrd”这个rd其实就是ramdisk的一个缩写,还是和之前一样(ramdisk是一个选项。选项后紧跟这initrd这个部分,这个部分就是关于ramdisk这个设备的设备信息)。


ram3.png


如图,我们在这里说到地址,因为在我们的内存中是不能随便指向的, 比如内存(图中大的长方形)中知道它的基地址是2000开头的(0x2000 0000)在这个地址中我们把2000 8000这个位置上放了我们的内核(图中大长发形中间的四边形)那很显然如果文件系统的数据也放在这个位置上,那是不是就可能把内核给冲掉,所以说这样就不太符合我们的要求,所以说至少ramdisk的基地址也就是图中的圆圈在内核的大小上在往上偏移,所以说为了满足我们这个程序整体的需求,我就做了更加机智的选择。内核应该在我们的基地址也就是说低地址上运行,那么文件系统我们就尽量把它放在内存的高地址上运行。这样两者怎么样都不会交叉,比如说数据它至少不会出现覆盖,所以这也是一个比较完美的解决方案。所以说我们在这个地方把文件系统尽量往高处放,所以我们的命令是“initrd=0x21000000,8M ”(=后面就代表内存的地址)这个地址只要不超过ramdisk的大小还有就是不超过我们整个内存的大小。


还没有完,因为我们对于内核启动ramdisk它一个是要告诉我们ramdisk的基地址还有就是因为内存还是很庞大,所以还是要指定数据的起点和终点。而这个终点我们不是通过地址来指定的而是通过一个大小也就是说我们会写一个告诉内核,我到底是要用多大的空间,那么这个空间就是8M,因为我们等一下会给大家已经做好了的是8M,也就是默认解压是8M,所以说我们在内存解压过后也是8M这样一个空间。


那么具体怎么做,我们后面会讲,假设我们做好过后,我们通过这两个选项是告诉内核通过这个两个中的哪个起始地址和大小来继续做根文件系统的启动,所以这样的话基本就已经结束了。然后后面一样的“init=/linuxrc”,没有什么变化,其次就是“console=ttySAC0”这就是我们对于启动参数来说,但是我们测试中我们有一个问题。测试首先我们在内存中来说,在我们的2000080000的位置上先把我们的Ulmage也就是“ 20008000 uImage”但是在我们内存中同样的问题21000000这个位置上应该放上initrd.img.gz,这样我们内核才能去找到这个东西。


所以现在我们来看如下图:


ram4.png


如图,这个是我们给大家已经做好的文件系统,在这个文件系统中有个压缩包“inited.img.gz”gz这种格式是Linux下比较通用的格式,那么我们以压缩包的形式传递应该说数据量比较小,所以传输速度很快。其次还有一个好处就是我们内核一般来说就可以对gz这样一个格式自己解压。解压过后他在操作起来会更加方便一些。所以说我们应该存放一个“ 21000000 initrd.img.gz”这样的文件,那么这个文件存放完过后,内核在根据你启动参数的地址就能找到这个文件。因为是gz格式所以它会自动解压,解压后就会释放出8M的空间。


所以说,以上就是总的流程。



【本文由麦子学院独家原创,转载请注明出处并保留原文链接】

logo
© 2012-2016 www.maiziedu.com
蜀ICP备13014270号-4 Version 5.0.0 release20160127

免费领取价值1888元求职宝典!

客服热线 400-862-8862

回到顶部