接着前边内核移植的文章,记录根文件系统的构建。

这里要用到强大的busybox,我选择的版本是busybox-1.18.5.tar.bz2 ,1.17的也可以;之所以选择这个版本是因为基于现在的交叉编译环境,可以正常静态编译busybox的版本貌似就是1.17之后的了(之前测试的是这样),当然用动态的也可以。

这里我讲述两种构建(静态和动态)形式都记录一下。正好这两种构建模式分别与TQ2440开发板手册和嵌入式Linux开发完全手册是对应的,所以整个流程都是参照这两份材料进行的。

根文件系统的构建到底是做什么的呢?说白了就是制作好一个文件目录,按照OS正常启动的必要需求,在对应的位置放上对应的需要的文件和应用程序(比如经常用到的一些命令[不过命令并不是制作文件系统所必须的,只是为了后边维护时用着方便,这也是busybox的实际存在意义,它集成了很多可用于嵌入式的管理命令和系统命令,还有系统启动所必须的一些东西,如init])。另一方面也说明了根文件系统的某些特性,它对应着内核的接口,按照一定的规范,实现了用户和内核的交互(shell,和目录树),这也是为什么有句话说“挂载根文件系统”。其实文件系统也并不是所有工程所必须的。一切都由需求而定。

首先进行的是动态编译的简单构建,比较简单。并没有配置很多很多用户和一些预期要用到的文件,只是实现了可以挂载以及busybox集成的命令工具,可以用于arm Linux的驱动开发和测试。

1、 编译busybox

这里,在busybox解压后的目录里,运行make menuconfig会看到和kernel一样的配置菜单,可以对其进行配置,大多配置项都是对一些命令支持的选择。有一点用到了必须说一下,就是是否静态编译的选项:

Busybox Settings  --->

Build Options  --->

[ ] Build BusyBox as a static binary (no shared libs)

这里我们先用动态编译。动态编译的话,在配置好文件系统后,要把编译时动态连接到的库手动的拷贝到对应的目录中。

这里就用默认的了(其实默认的配置基本上是所有功能都选上了,图个懒么,万一将来用到选项没有配上,还得回来重新配上,重新编译,重新制作镜像,重新烧写。。。)

编译时改Makefile

ARCH ?=arm #1.18版的busybox190(我也纠结着俩哥们怎么分开了)

CROSS_COMPILE ?=arm-linux- #1.18版本的在164

然后我们在工程目录中建一个目录fs1,来存放我们的这个文件系统,即/home/jun/arm/fs1.

弄好以后,执行命令:(ps:busybox目录下)

$ make CONFIG_PREFIX=/home/jun/arm/fs1 install

待到编译完成以后,会在fs1目录下生产bin  linuxrc  sbin  usr,证明我们已经有了强大功能的命令和工具集,接下来就可以构建我们的根文件系统了。

因为编译是动态链接的,所以我们要把动态链接库准备好,我们是用的arm-linux-gcc编译的,当然用的就是glibc的库喽,去交叉编译器的目录下找一下。

busybox目录下执行:

$ arm-linux-readelf -a ./busybox|grep "Shared"

会列出sharedlib,我的列出来的是:

0x00000001 (NEEDED)                     Shared library: [libm.so.6]

0x00000001 (NEEDED)                     Shared library: [libc.so.6]

然后我们就把这两个依赖到的链接库拷贝到fs1/lib(没有这个目录就创建一个,我们本来就是在构建根文件系统),另外动态链接还要用到加载器,这里只会看到依赖的库,要手动的复制加载器过来,就是ld-linux.so.3

我的所以库都在交叉编译工具目录下的 /home/jun/arm/4.3.3/arm-none-linux-gnueabi/libc/lib 下边,你ls–l 一下发现有玄机,就是我们需要用到的几个文件libm.so.6、 libm.so.6、ld-linux.so.3都是链接文件,实际指向的是:

lrwxrwxrwx   1 jun jun      11 2011-09-20 17:32 libc.so.6 -> libc-2.8.so

lrwxrwxrwx   1 jun jun      11 2011-09-20 17:31 libm.so.6 -> libm-2.8.so

lrwxrwxrwx   1 jun jun       9 2011-09-20 17:31 ld-linux.so.3 -> ld-2.8.so

所以我们不但要把链接文件cpfs1/lib中,还要把连接到的文件cp过去:

$ cp libc.so.6 libm.so.6 ld-linux.so.3 libc-2.8.so libm-2.8.so ld-2.8.so /home/jun/arm/fs1/lib

2、 构建根文件系统。

主要构件的目录为/etc/dev。其他的目录一条命令就OK了。

这里的/dev要用busybox提供的mdev来实现。

mdev busybox自带的一个简化版的udev, 适合于嵌入式的应用埸合。 其具有使用简 单的特点。它的作用,就是在系统启动和热插拔或动态加载驱动程序时,自动产生驱动程序 所需的节点文件。 在以busybox为基础构建嵌入式linux的根文件系统时,使用它是最优的选择。默认的配置单中已经加入了mdev的支持。优秀的mdev不但可以动态更新dev目录,还支持热插拔。

不但busybox要添加对mdev的支持,内核也要添加,因为这个必须有内核的底层支持才可以动态识别设备变更、动态创建设备文件。主要是通过添加内核对sysfstmpfs文件系统的支持,因为udev其实是通过读取sysfs信息来动态构建的设备文件:所以在内核中设置CONFIG_SYSFSCONFIG_TMPFS配置项:

找不到可以在配置项里搜索一下:

| Symbol: SYSFS [=y]                                                                |

| Prompt: sysfs file system support                                                 |

|   Defined at fs/sysfs/Kconfig:1                                                   |

|   Depends on: EMBEDDED                                                            |

|   Location:                                                                       |

|     -> File systems                                                               |

|       -> Pseudo filesystems                                                       |

|   Selected by: GFS2_FS && BLOCK && EXPERIMENTAL && (64BIT || LBD) && GFS2_FS_LOCK |

|                                                                                   |

+--------------------------------- Search Results ----------------------------------+

| Symbol: TMPFS [=y]                                                                |

| Prompt: Virtual memory file system support (former shm fs)                        |

|   Defined at fs/Kconfig:99                                                        |

|   Location:                                                                       |

|     -> File systems                                                               |

|       -> Pseudo filesystems                                                       |

|                                                                                   |

|                                                                                   |

| Symbol: TMPFS_POSIX_ACL [=y]                                                      |

| Prompt: Tmpfs POSIX Access Control Lists                                          |

|   Defined at fs/Kconfig:111                                                       |

|   Depends on: TMPFS                                                               |

|   Location:                                                                       |

|     -> File systems                                                               |

|       -> Pseudo filesystems                                                       |

|         -> Virtual memory file system support (former shm fs) (TMPFS [=y])        |

|   Selects: GENERIC_ACL                                                            |

+---------------------------------------------------------------------------(100%)--+

搜索结果可以看出,两个都主要依赖于下边选项,都选上,重新编译我们的内核镜像就好了。

-> File systems

-> Pseudo filesystems

其实上述选项也是默认的都选好的。

好的,开始喽……

a.构建/etc    /*这里的/—根目录指的是fs1,这就是我们构建的根目录,制作镜像时就是把fs1的整个目录及子目录打包成镜像的*/

$ mkdir etc

$ touch etc/inittab

$ chmod 777 inittab

$ vi etc/inittab       #vi编辑器打开并加入如下内容

#/etc/inittab

::sysinit:/etc/init.d/rcS

s3c2410_serial0::askfirst:-/bin/sh

::ctrlaltdel:/sbin/reboot

::shutdown:/bin/umount -a -r

$ cd etc

$ mkdir init.d

$ touch init.d/rcS

$ chmod 777 rcS

$ vi init.d/rcS  #vi编辑器打开并加入如下内容

#!/bin/sh

ifconfig eth0 192.168.1.111

mount -a

mkdir /dev/pts

mount -t devpts devpts /dev/pts

echo /sbin/mdev > /proc/sys/kernel/hotplug

mdev –s

$ touch fstab

$ vi fstab #vi编辑器打开并加入如下内容

proc    /proc   proc    defaults        0       0

tmpfs   /tmp    tmpfs   defaults        0       0

sysfs   /sys    sysfs   defaults        0       0

tmpfs   /dev    tmpfs   devaults        0       0

OK,基本上差不多了,接下来是创建几个必要的设备文件,和其他目录:

因为mdev是一个程序,程序的运行就要创建进程,而linux的第一个进程是init进程,init进程至少要用到设备文件:/dev/console/dev/null。所以先创建这两个设备文件:

$ cd /home/jun/arm/fs1/ #确保当前是在fs1目录下

$ mkdir dev

$ cd dev

$ sudo mknod console c 5 1

$ sudo mknod null c 1 3

然后是创建其他必要的目录:

$ mkdir proc mnt tmp sys root

Ok,构建完成。可以用来制作镜像。

$ mkyaffs2image fs1 fs1.bin #/home/jun/arm/

烧入板子测试一下先。。。。。。。。。。。。

额,报错如下:

……

yaffs_read_super: isCheckpointed 0

VFS: Mounted root (yaffs filesystem) on device 31:2.

Freeing init memory: 120K

Warning: unable to open an initial console.

Failed to execute /linuxrc.  Attempting defaults...

Kernel panic - not syncing: No init found.  Try passing init= option to kernel

……

解决方法: /*估计是创建的设备节点的权限问题,所以删掉重新创建*/

$ cd /home/jun/arm/fs1/dev

$ rm –f  *

$ sudo mknod -m 660 null c 1 3

$ sudo mknod -m 660 console c 5 1

然后重新制作文件系统镜像,并烧写测试。。。。。。。。。。。。。。。。。。

不行,由此看来不单单是权限的而问题了,我查看了一下Uboot(这里是TQ自带的Uboot)的启动命令参数:

bootargs=noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0

因为我们用的是mdev自动生成的设备文件,所以他默认的是s3c240_serial0s3c240_serial1s3c240_serial2……我们把启动参数改一下试试:

输入q可以进入uboot的命令模式。然后输入help或者?可以列出所以的可用命令。

原来的启动参数是:bootargs=noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0;我们重新设置为:bootargs=noinitrd root=/dev/mtdblock2 init=/linuxrc console=s3c2410_serial0

设置命令是:

> setenv bootargs 'noinitrd root=/dev/mtdblock2 init=/linuxrc console=s3c2410_serial0'

> saveenv

然后启动内核就没有输出了:

Start Linux ...

Copy linux kernel from 0x00200000 to 0x30008000, size = 0x00200000 ... Copy Kernel to SDRAM done,NOW, Booting Linux......

Uncompressing Linux.......................................................................................................................... done, booting the kernel.

然后就没有下文了,显然是没有输出了。看来还是console得问题。我们为了还原回去,证明是改为console=s3c2410_serial0造成的,我们重新设置回去:

> setenv bootargs 'noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0'

> saveenv

看来还是理解不到位造成的。因为这一换原来的输出也没有了,这证明不是串口加载对接的问题,比较没有对接好的话是没有输出的。回复后报错依旧是:

yaffs_read_super: isCheckpointed 0

VFS: Mounted root (yaffs filesystem) on device 31:2.

Freeing init memory: 120K

Warning: unable to open an initial console.

Failed to execute /linuxrc.  Attempting defaults...

Kernel panic - not syncing: No init found.  Try passing init= option to kernel.

[<c002c700>] (unwind_backtrace+0x0/0xdc) from [<c02b69d0>] (panic+0x40/0x110)

[<c02b69d0>] (panic+0x40/0x110) from [<c00264c0>] (init_post+0xcc/0xf4)

[<c00264c0>] (init_post+0xcc/0xf4) from [<c000859c>] (kernel_init+0xb8/0xe0)

[<c000859c>] (kernel_init+0xb8/0xe0) from [<c004812c>] (do_exit+0x0/0x578)

[<c004812c>] (do_exit+0x0/0x578) from [<00000001>] (0x1)

+++++++++++++++++++++++++++美丽的分割线++++++++++++++++++++++++++++

中间因为换电脑,台式机换笔记本,再回来做开发确实挺纠结的,另外还是win7的系统,驱动问题很纠结。有同样问题的朋友可以看我的另一篇文章,《 》,有介绍相关问题的解决办法。

Well ,大多数网上给的上边问题的解决办法都是说你没有创建consolenull设备文件,显然不是这样,那是为什么呢?我也查了一番资料,确实良久无果,最后,就是今天一不小心调好了。因为之前不知道编好的程序没法烧到板子里,所以改好东西后隔了一天才验证了其正确性,努力的回想我的改动,应该还是源于这篇文章的:WARNING: Unable to open an initial console ,我主要只改了一下内核配置:

内核选择如下选项:

Device Drivers  --->

Character devices  --->

[*] Virtual terminal

Serial drivers  --->

<*> 8250/16550 and compatible serial support

[*]   Console on 8250/16550 and compatible serial port

(2) Maximum number of 8250/16550 serial ports

(2) Number of 8250/16550 serial ports to register at runtime

[*] Unix98 PTY support

原来默认的应该是84(上边的Maximum number...Number of...);改过后重新编译内核;又到之前构建的根文件系统下的/dev下,把原来的consolenull删除了,重新构建一下。就好了:

(虽然挂载成功,但还是有两个小问题的,ifconfigtmpfs有问题。)

/dev下有大量的设备文件:一方面说明我们的mdev工作正常;另一方面也说明我们的内核只是简单的移植,没有进一步做优化和裁剪,才使得有这么多实际无用的设备文件。

OK,根文件系统移植的第一阶段就在此画上完美的句号吧。现在可以用于驱动开发了。

构建根文件系统(一)相关推荐

  1. 教你用 buildroot 构建根文件系统

    如果想要构建完整的根文件系统,大家一般都是使用buildroot,它不仅包含了 busybox 的功能,而且里面还集成了各种软件,需要什么软件就选择什么软件,不需要我们去移植. 嵌入式系统三大部分:b ...

  2. buildroot构建根文件系统

    buildroot构建根文件系统 一.简介 Buildroot是Linux平台上一个构建嵌入式Linux系统的框架.整个Buildroot是由Makefile脚本和Kconfig配置文件构成的.本文使 ...

  3. Buildroot 构建根文件系统(Jz2440)

    1. Buildroot 简介      Buildroot是Linux平台上一个构建嵌入式Linux系统的框架.整个Buildroot是由Makefile脚本和Kconfig配置文件构成的.你可以和 ...

  4. 野火i.MX6ULL Pro开发板构建根文件系统

    眼瞅着2020年马上就要到头了,承诺给大家的Linux移植三部曲还差最后一篇,这个拖延癌晚期恐怕今年是治不好了,不到最后的DL绝不妥协-- (这句话是年前写的,写了个开头就疫情了,封城,电脑丢在了公司 ...

  5. 从零开始构建根文件系统

    以下内容源于网络资源的学习与整理,如有侵权请告知删除. 参考博客 Uboot和系统移植(19)------- 根文件系统构建过程详解_big__C的博客-CSDN博客 一.总结 (1)本节在前面的理论 ...

  6. 嵌入式中利用ubuntu-base构建根文件系统

    在嵌入式环境中,我们最常用busybox.yocto或buildroot来构建根文件系统,这种情况下,当我们需要使用一些组件的时候,往往需要我们使用源码编译,移植到开发板中.那有没有像ubuntu的文 ...

  7. 【ARM】使用Ubuntu-base构建根文件系统

    使用Buildroot构建根文件系统 介绍 资源下载 配置根文件系统 设置软件源 安装必要软件 添加新用户 设置主机名称和本机IP 设置终端串口 网络DHCP FTP服务器搭建 串口无法登录 开机启动 ...

  8. 笔记:使用buildroot构建根文件系统

    文章目录 简介 构建过程 buildroot包下载 配置 Target options配置项 Build options配置项 Toolchain配置项 System configuration配置项 ...

  9. 【ARM】使用Busybox构建根文件系统

    Busybox构建根文件系统 介绍 下载 配置busybox 配置交叉编译器 取消静态库编译 添加vi命令的支持 取消简化模块 支持mdev 中文支持 编译 完善根文件系统 创建必要文件夹 复制库 启 ...

最新文章

  1. python在线编辑器最新_skulpt搭建Python在线编译器(一):下载、安装
  2. win8改win7笔记
  3. “生于忧患,死于安乐”之程序员人生
  4. 最短路径-Floyd(佛洛伊德算法)
  5. ug添加imachining变量_UG用的不够快?是不是还没建标准库
  6. 小程序入门学习12--云函数与数据库01
  7. boost::asio async_write也不能保证一次发完所有数据 二
  8. python pickle反序列化漏洞_渗透测试 - 黑客技术 | 【技术分享】记CTF比赛中发现的Python反序列化漏洞_吾爱漏洞...
  9. 家庭医疗系统-基于蓝牙无线通信技术
  10. java使用elasticsearch进行模糊查询-已在项目中实际应用
  11. 数字电子技术基础阎石老师第五版课后习题解答-很抱歉,其实才写了两道题,大家不要误点进来耽误时间了。但是开始写了又不想删掉,希望日后能补起来吧。
  12. pcie gen3 bios设置_性价比无敌or搞笑? A卡传统回来了!(附刷bios教程)
  13. 第四章——波形与矢量AWGN信道
  14. DTI | Drug-target interaction | 基础知识
  15. 考研经验帖——特别说明很适合8月才开始准备的小伙伴
  16. MFC+Halcon 真正实现图像缩放、平移
  17. 用1、3、5、7 这4 个数字,能组成的互不相同且无重复数字的三位数有哪些?共有多少个?这些数的和为多少?
  18. 真假屏幕测试软件,四个小技巧,检测 iPhone 屏幕是否为原装屏
  19. 《数据库原理》学生表,课程表,选课表的相关内容
  20. Python多线程结合队列下载百度音乐的方法

热门文章

  1. TOEFL战地手记听力FAQ
  2. burp抓不到手机app请求包
  3. 注销linux用户的方法,Linux下注销登录用户的方法
  4. 盘点40余款好用的项目管理软件
  5. 【CSS3】一文搞懂盒子模型
  6. 超漂亮的前台页面模板——html+css+js+框架
  7. 关于表单防重复提交一些东东
  8. 莫纳什大学计算机硕士专业怎么样,澳大利亚留学:莫纳什大学计算机硕士的14个专业...
  9. 如何把立创EDA上导出的原理图和封装导入AD的元件库
  10. 【测试用例】文本框测试用例