前言
最近翻出来十年前的ARM9开发板:AT91SAM9261EK,芯片是原Ateml的AT91系列,之前开发的资料,因为更换电脑,基本上找不到了,还好部分经验记录在了【博客】上,所以,这次为了继续学习总结整个嵌入式Linux的开发方法,【宝刀未老】的ARM9 开发板重新上电,开启嵌入式Linux学习研究之旅Atmel 官方有比较全面的资料,地址为:/bin/view/Linux4SAM/嵌入式开发是一个【动手】实践的综合学科,如果不【亲自动手】,你永远不了解技术的实现细节,也无法感受到解决一个个难题带来的【喜悦】,就像是【游泳或是骑自行车】,理论经验再丰富,不【亲自】持续性的练习,依旧是个【门外汉】流程介绍
目前接触到很多支持Linux的芯片,大多数:ROM-Less,也就是本身的SRAM与Flash容量有限,如果跑Linux,需要外部的SDRAM、DDR SDRAM、NandFlash、NorFlash、SD卡等。这牵涉到一个基本的问题:从哪个存储设备启动的问题,NandFlash、SD卡,本身不具备【随机存储】的能力,不能直接启动,只作为【存储代码】的作用,启动时,需要把【代码】拷贝到SDRAM中(容量大,DDR 也是SDRAM的一种)AT91系列的SOC MPU,本身有ROM,可以通过硬件的片选,选择启动方式,AT91SAM9216-EK这个开发板,可以使用NandFlash启动,但需要 Atmel提供的:BootStrapAT91的BootStrap 可以继续引导 U-Boot, U-Boot 继续引导Linux,Linux 运行起来,需要【根文件系统】,本篇研究【根文件系统的制作】与【运行】根文件系统
烧写了BootStrap、U-Boot、uImage(Linux内核),系统并没有跑起来,原因就是还需要个【根文件系统】,这个根文件系统的文件类型,可以是jffs2、yaffs2、cramfs、ubifs等,我这里先使用:cramfs根文件系统的文件格式定好了,还需要【原材料】,也就是需要构建一个【根文件系统】的包。Linux中的【一切皆文件】思想说明,需要创建一个个的目录或是文件,最后把这些目录文件按指定的文件格式打包一下,烧写到开发板的存储设备中,如NandFlash中,如SD卡中没有根文件系统
没有根文件系统,Linux 内核根本跑不起来,会报类似下面的错误VFS: Cannot open root device "mtdblock7" or unknown-block(31,7): error -5Please append a correct "root=" boot option; here are the available partitions:1f00 256 mtdblock0 (driver?)1f01 512 mtdblock1 (driver?)1f02 256 mtdblock2 (driver?)1f03 256 mtdblock3 (driver?)1f04 256 mtdblock4 (driver?)1f05 512 mtdblock5 (driver?)1f06 6144 mtdblock6 (driver?)1f07122880 mtdblock7 (driver?)Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(31,7)
制作流程
先制作最小的根文件系统,让Linux内核跑起来,首先是下载:BusyBox,生成根文件系统必须的初始化与shell命令等这部分参考:【busybox-1.35.0】嵌入式Linux编译有了BusyBox 这个 小工具集,还缺失一些Linux必须的文件,操作如下/etc 目录
这里需要三个文件: 注意这个是烧写到开发板上的目录结构,本地在rootfs目录下,创建时需要注意,移除 最前面的/
/etc/inittab
/etc/fstab
/etc/init.d/rcS
/etc/inittab
参考的文件内容如下:::sysinit:/etc/init.d/rcS ::askfirst:-/bin/sh ::ctrlaltdel:/sbin/reboot ::shutdown:/bin/umount -a -r
/etc/fstab
proc /proc proc defaults 0 0 sysfs/sys sysfs defaults 0 0 devtmpfs /dev devtmpfs defaults 0 0 tmpfs/tmp tmpfs defaults 0 0 tmpfs/var tmpfs defaults 0 0
/etc/init.d/rcS
#! /bin/sh mount -t sysfs none /sysmount -t proc none /procmount -t tmpfs tmpfs /tmpmdev -s
这个文件需要改为【可执行属性】,如chmod +x etc/init.d/rcS
,注意这里不使用/etc
,而是etc
,原因是相对:rootfs 目录,而不是【开发主机的】目录/etc
/dev 目录
注意这个是烧写到开发板上的目录结构,本地在rootfs目录下的 dev (相对目录)这里需要创建dev/console
与dev/null
两个设备用于启动Linux系统mknod -m 600 dev/console c 5 1mknod -m 600 dev/null c 1 3
其他目录
需要把 BusyBox 的【产物】,也就是 _install 目录下的所有目录文件,【拷贝】到 rootfs下可以创建几个【空目录】mkdir root boot tmp var sys proc lib mnt home usr
文件打包
这里使用cramfs 文件,原因就是简单方便,验证Linux 内核正常跑起来,后面再研究其他的文件系统,如:jffs2、yaffs2、ubifs等ubuntu 安装 :mtd-tools 工具apt-get install mtd-tools
cramfs 打包:mkfs.cramfs rootfs_01 rootfs_01.img
,这里的后缀意义不大,注意用于自己识别哪个是打包后的文件而已,可以改后缀为.bin
烧写验证
这里使用AT91SAM9261KE,需要依次烧写:BootStrap、u-boot.bin、uImage、rootfs_01.img,注意这里使用NandFlash,烧写在NandFlash指定的地址下注意事项一
内核需要开启【指定文件系统】的支持,如这里是:cramfs,需要在Linux内核编译时开启注意事项二
uboot 默认会传递:bootargs 给到内核,这里需要改下:rootfstype=cramfs
,并且增加一条init=/linuxrc
修改方法可以直接修改 uboot 的文件,也可以在启动后,进入uboot的命令行,使用命令修改U-Boot> setenv bootargs 'console=ttyS0,115200 earlyprintk mtdparts=atmel_nand:256k(bootstrap)ro,512k(uboot)ro,256k(env),256k(env_redundant),256k(spare),512k(dtb),6M(kernel)ro,-(rootfs) root=/dev/mtdblock7 rw rootfstype=cramfs init=/linuxrc'U-Boot> saveenv Saving Environment to NAND...Erasing redundant NAND...Erasing at 0x100000 -- 100% complete.Writing to redundant NAND... OKU-Boot> reset
cramfs 启动信息
备注
创建根文件系统的脚本,根据网上类似的脚本改了一下#!/bin/bashecho "------Create rootfs start...--------"rootfs=$1rm -rf $rootfsmkdir $rootfscd $rootfsecho "--------Create root,dev....----------" mkdir root dev etc boot tmp var sys proc lib mnt home usrmkdir etc/init.d etc/rc.decho "make node in dev/console dev/null"sudo mknod -m 600 dev/console c 5 1sudo mknod -m 600 dev/null c 1 3# create etc config /etc/inittabecho -e "::sysinit:/etc/init.d/rcS " >etc/inittabecho -e "::askfirst:-/bin/sh " >>etc/inittabecho -e "::ctrlaltdel:/sbin/reboot " >>etc/inittabecho -e "::shutdown:/bin/umount -a -r " >>etc/inittab# create etc config /etc/init.d/rcsecho -e "#! /bin/sh " >etc/init.d/rcSecho -e "mount -t sysfs none /sys " >>etc/init.d/rcSecho -e "mount -t proc none /proc " >>etc/init.d/rcSecho -e "mount -t tmpfs tmpfs /tmp" >>etc/init.d/rcSecho -e "mdev -s " >>etc/init.d/rcSchmod +x etc/init.d/rcS# create etc config /etc/fstabecho -e "proc /proc proc defaults 0 0 " >etc/fstabecho -e "sysfs/sys sysfs defaults 0 0 " >>etc/fstabecho -e "devtmpfs /dev devtmpfs defaults 0 0 " >>etc/fstabecho -e "tmpfs/tmp tmpfs defaults 0 0 " >>etc/fstabecho -e "tmpfs/var tmpfs defaults 0 0 " >>etc/fstabecho "-------make rootfs done---------"
【注意】脚本需要【可执行属性】,制作方法:cr_fs.sh rootfs_02
,后面跟个rootfs的目录名字制作后,只需要把 BusyBox 生成(make install)后的产物,复制到 rootfs下最后使用 mkfs.cramfs xx_fs xx_fs.bin 即可生成 cramfs的根文件系统,这个 xx_fs.bin 可以直接烧写到NandFlash上