注意路径一定要写对,否则将不会有效。重新登录系统(不必重启机器,开始->logout 即可),使以上设置生效,在命令行输入arm-linux-gcc –v,会出现如下信息,这说明交叉编译环境已经成功安装。
七、Bootloader文件的原理、移植和编译
1、uboot代码移植
首先执行如下命令,分别创建工作目录/opt/FriendlyARM/mini6410/linux和临时目录,并把光盘中linux 目录中的所有文件都复制到/tmp/linux 目录中,
#mkdir –p /opt/FriendlyARM/mini6410/linux
#mkdir /tmp/linux
然后在工作目录/opt/FriendlyARM/mini6410/linux 中执行解压安装U-boot 源代码
#tar xvzf /tmp/linux/ u-boot-mini6410-20101106.tar.gz
将u-boot代码加压到opt/FriendlyARM/mini6410/linux/u-boot-mini6410目录下。
uboot代码目录结构:
板级移植需要修改的板级配置文件:
在 opt/FriendlyARM/mini6410/linux/u-boot-mini6410目录下找到makefile文件,打开文件可以看到几个相关的编译选项,如下:
mini6410_nand_config-ram128 // 为系统内存128M,从NANDFLASH启动的设备生成编译配置文件
mini6410_sd_config-ram128 // 为系统内存128M,从SD卡启动的设备生成编译配置文件
mini6410_nand_config-ram256 // 为系统内存256M,从NANDFLASH启动的设备生成编译配置文件
mini6410_sd_config-ram256 // 为系统内存256M,从SD卡启动的设备生成编译配置文件
进入uboot源代码根目录:cd /opt/FriendlyARM/mini6410/linux/u-boot-mini6410
生成配置文件:make mini6410_nand_config-ram256
开始编译:make
最终生成u-boot.bin文件,用于下载到FLASH上。为了便于区分,可以将u-boot.bin文件改名为u-boot_nand-ram256.bin。
另外,我们也可以选择编译用于SD卡启动的uboot文件。
要把新编译生成的u-boot.bin下载到开发板的FLASH上,需要先用SD卡上的uboot启动6410开发板,SD卡启动在串口下显示如下用户菜单:
[f]:输入f,格式化FLASH,如上图所示,
[v]:输入v,将uboot.bin文件下载到FLSAH上,如下图所示:
注意,下载uboot时需要使用dnw.exe工具,且只有先输入v以后,dnw.exe工具上的状态才会显示[USB:ok]
将uboot下载到FLASH以后,切换启动开关后,单板重新上电,启动FLASH上的uboot,如下图所示:
上面菜单中的选项,首先要了解[k],下载linux内核镜像文件,下载内核文件之前,我们需要先编译得到linux内核文件。
八、Linux内核文件的原理、移植和编译
1、Liinux内核代码移植
进入工作目录/opt/FriendlyARM/mini6410/linux 执行,如下命令,生成生成linux-2.6.38 目录,如下图所示
#tar xvzf /tmp/linux/ linux-2.6.38-20110325.tar.gz
2、Linux内核代码编译,首先进入linux-2.6.38 目录,
#make distclean
【2】配置内核,生成新的配置文件 .config
#make menuconfig ARCH=arm
Tiny6410开发板已经为我们准备好了相关的配置文件,所以这一步可以省略。Tiny6410原配的是4.3寸的触摸屏,所以使用config_mini6410_n43作为内核编译的配置文件。
【3】编译内核
#make uImage ARCH=arm CROSS_COMPILE=arm-linux-
输入#make zImage,开始编译内核,在arch/arm/boot 目录下生成linux 内核映象文件zImage。
将编译得到的内核镜像文件zImage通过uboot下载到FLASH上运行,
内核在启动期间进行的最后操作之一就是安装根文件系统,并读取根文件系统中的配置文件,所以接下来我们要学习根文件系统。
九、制作用于Linux内核启动的根文件系统
1、根文件系统的作用和工作原理
首先,根文件系统是Linux(或者说是UNIX类)操作系统运行时所需要的特有文件系统。根文件系统不仅具有普通文件系统的存储数据文件的功能,还被操作系统用来存储运行时所需要的一些特殊文件。这些特殊文件包括:busybox (提供 shell 命令集)、配置文件(通常位于/etc目录下用来初始化和布局你的文件系统)、设备文件(位于/dev目录下)、必要的库文件。设备文件实际上保存着对应设备的一些相关参数,操作系统通过使用它们来与应用程序进行接口,并与设备进行交互。因此根文件系统是Linux运行时所必须的。
另外,为了让内核文件的大小合适,不可能把所有的功能都编译到内核文件中,所以有些内核需要的功能是以内核模块的形式存在的(例如一些驱动程序)。为了使内核文件在运行的时候可以找到并加载这些内核模块, 就需要将内核模块保存在根文件系统中。其实根文件系统就是一个普通的文件,它的制作过程是:
(1)按照Linux内核要求,制作根文件系统的所需要的根目录和子目录,
(2)将内核运行需要的文件编译并保存到正确的目录,
(3)使用专门的工具将整个目录转换成合适的镜像文件,这个文件可以直接烧写到存储设备上去。
2、手动创建根文件系统目录和文件:这个工作和系统的存储介质无关
#mkdir rootfs
#cd rootfs
#mkdir bin dev etc lib proc sbin sys usr mnt tmp var
#mkdir usr/bin usr/lib usr/sbin lib/modules
(2)创建设备文件(如果不创建这两个设备文件,在文件系统启动时会出现错误信息,不能初始化控制台。)
#cd dev/
#mknod -m 666 console c 5 1
#mknod -m 666 null c 1 3
#cd..
(3)安装/etc目录
/etc目录下是一些配置文件etc/inittab etc/profile etc/fstab etc/init.d/rcs和具体硬件无关,各种机器上的这些配置文件大同小异可以复用。
因为这些配置文件和系统启动相关,所以在学习配置文件之前,先简单了解一下系统的启动过程:
在linux内核启动到start_kernel()函数的最后,通过调用init()函数,创建第一个核心线程,核心线程主要进行一些外设初始化工作,包括调用do_basic_setup()完成外设及其驱动程序的加载和初始化,完成文件系统初始化和root文件系统的安装。当do_basic_setup()函数返回init(),init()又打开了/dev/console设备,重定向三个标准的输入输出文件stdin、stdout和stderr到控制台,最后,搜索文件系统中的init程序(sbin目录下的init文件,其实也是busybox文件)或者由init=命令行参数指定的程序,并使用 execve()系统调用加载执行init程序。此时Linux完成内核启动,开始运行init程序,init程序需要读取配置文件/etc/inittab。所以inittab是系统执行的第一个配置文件。当 Busybox 的初始化程序执行时,首先试图在/etc 下查找启动文件inittab,如果找到则按照inittab 文件定义的顺序执行;如果找不到inittab,则默认执行/etc/init.d/rcS 脚本,之后启动相应的 shell。在 Busybox 的inittab 文件中,通常定义系统初始化时执行的也是/etc/init.d/rcS 脚本。也就是说,无论inittab 文件的存在与否,Busybox 初始化时,都会先执行rcS 脚本。
所以,接下来我们需要学习的是:
1、inittab文件结构
2、rcS脚本语法
inittab文件中每个登记项的结构都是一样的,分别以冒号“:”分隔的4个字段。具体如下:
identifier : run_level : action : process
其中,各字段以及与其相关的说明如下:
identifier:登记项标识符,最多为4个字符。用于惟一地标识/etc/inittab文件中的每一个登记项
run_level:系统运行级,即执行登记项的init级别。用于指定相应的登记项适用于哪一个运行级,即在哪一个运行级中被处理。如果该字段为空,那么相应的登记项将适用于所有的运行级。在该字段中,可以同时指定一个或多个运行级,其中各运行级分别以数字0.1.2.3.4.5.6或字母a、b、c表示,且无需对其进行分隔。
action:动作关键字。用于指定init进程对相应进程(在“process”字段定义)所实施的动作。具体动作包括:
1、boot:
2、bootwait:
3、initdefault:
4、off:
5、once:
6、ondemand:
7、powerfail
8、powerwait
9、respawn
10、sysinit
11、wait:
process:所要执行的shell命令。任何合法的shell语法均适用于该字段。
嵌入式Linux系统的inittab文件没有运行级别的概念,所以大致的内容如下:
::sysinit:/etc/init.d/rcS ## 指定系统启动后首先执行的文件
::respawn:-/bin/login -f root ## 自动作为root账户登录
::askfirst:-/bin/sh ## 类似respawn,它将会促使init在控制台上显示“Please press Enter to active this console”的信息,并在重新启动之前等待用户按下enter键
::ctrlaltdel:/sbin/reboot ## 设置ctrl+alt+del键对应的动作(重启文件系统)
::shutdown:/bin/umount -a -r ## 设置关机时对应的动作(卸载所有文件系统)
::restart:/sbin/init ## 设置系统重启时对应的动作(运行的init程序)
创建etc/init.d/rcS文件:rcS文件是一个脚本文件,借助这个脚本可以设置各种程序开机后自动运行,也可进行其他系统设置,类似于Windows系统中的自动批处理文件。
#!/bin/sh ## 符号#!用来告诉系统它后面的参数是用来执行该文件的程序
PATH=/sbin:/bin:/usr/sbin:/usr/bin ## 首先设置了PATH环境变量,只是为了后续命令使用方便
runlevel=S
prevlevel=N
umask 022
export PATH runlevel prevlevel
/bin/hostname zinix
/bin/mount -n -t usbfs none /proc/bus/usb
echo /sbin/mdev > /proc/sys/kernel/hotplug
/sbin/mdev -s
/bin/hotplug
# mounting file system specified in /etc/fstab
mkdir -p /dev/pts
mkdir -p /dev/shm
注意最后还要改变它的属性使它能够执行
创建etc/fstab文件:fstab文件描述系统中各种文件系统的信息,应用程序读取这个文件,然后根据其内容进行自动挂载的工作
device mount-point type options dump fsck order
文件中各字段的意义如下:
1)device:要挂接的设备,如/dev/mtdblockl;
2)mount-point:挂接点;
3)type:文件系统类型;
4)options:挂接参数,以逗号隔开;
5)dump和fsck order:用来决定控制dump、fsck程序的行为。
创建用户和组文件:
在etc目录下增加passwd和group两个文件。首先增加passwd文件,passwd一共由7个字段组成,6个冒号将其隔开。其含义分别为:
1)用户名;
2)是否有加密口令,x表示有,不填表示无,采用MD5、DES加密;
3)用户ID;
4)组ID;
5)注释字段;
6)登录目录;
7)所使用的shell程序。
passwd的内容为root:x:0:0:root:/root:/bin/sh
只有增加了passwd文件,启动以后命令行才会显示[root@zinix /]# ,否则只会显示[@zinix /]#
group共由4个字段组成,3个冒号将其隔开。含义分别为:
1)组名;
2)是否有加密口令,同passwd;
3)组ID;
4)指向各用户名指针的数组。
/home/work/rootby/etc/group内容如下:
root:x:0:
安装glibc库
在开发板上需要加载器和动态库,执行如下几个命令:
$mkdir-p/home/work/rootby/lib
$cd/home/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib
$cp*.SO*/home/work/rootby/lib-d
(4)编译内核模块
#make modules ARCH=arm CROSS_COMPILE=arm-linux-
(5)安装内核模块
#make modules_install ARCH=arm INSTALL_MOD_PATH=/XXX/rootfs
3、使用BusyBox制作根文件系统
BusyBox的作用与原理:根文件系统的目录下面除了放置内核运行需要的内核模块文件以外,还需要放置提供给用户使用的系统命令,例如:ls、cat之类。这些命令如果重头开发就太没意思了,所以有人搞了个busybox,这玩意编译完以后其实也就是一个应用程序,但是它实现了Linux系统大部分的命令(它的编译也需要使用make menuconifg命令生成指导编译的配置文件),将编译得到的busybox文件放置到根文件系统特定的目录,然后再建立一些软连接,这样面向用户的Linux系统命令就移植完成了。
bsuybox的编译视频:
打开busybox自带的FTP服务器:
方案1:在bin目录下创建软链接:ln -s busybox tcpsvd
这个tcpsvd就可以启动ftp服务器。然后输入命令:#tcpsvd 0 21 ftpd -w / &
// 上面的0表示对所有ip地址都进行侦听
// 21指定ftp服务器的默认端口
// ftpd -w这里的参数-w表示client可以对目录执行写操作
// 可以使用-t和-T参数设置client在没有任何操作的最大时间之后ftpd主动断开client连接
// 默认-t为2分钟=2 * 60,-T为1小时=1 * 60 * 60
// / ftp服务器开发的目录
// & 表示启用一个新的进程运行FTP服务器,否则当前shell被阻塞,直到下发Ctrl+c
设置以后,在IE浏览器输入:ftp://192.168.1.230/,可以访问单板上的 / 目录。
方案2:设置inetd.conf,并运行inetd。不知什么原因,暂时没搞定这个方案。
4、使用Initramfs制作根文件系统
【1】首先要通过make menuconfig ARCH=arm 配置Linux内核,
General Setup -> Initial RAM filesystem and RAM disk
【2】再选择创建好的根文件系统目录所在的路径:xxx/rootfs
【3】在根文件系统目录建立一个软连接:ln -s ./bin/busybox init
【4】重新编译内核:make uImage ARCH=arm CROSS_COMPILE=arm-linux-
【5】将编译好的内核文件下载到设备上运行即可(配置了Initramfs,编译得到的内核文件uImage比正常情况下大,因为内核文件已经包含了根文件系统)
5、使用NFS文件系统
在调试阶段,需要频繁的修改应用程序,每次都把编译好的文件下载到FLASH上进行调试并不是一个好主意(FLASH有寿命且下载时间也比较长),而使用NFS(网络文件系统)是一个好方法。所以接下来我们要重点介绍uboot启动菜单中的选项。
通过命令可以设置网络启动参数:
nfsroot 是连接6410开发板的Linux主机的IP 地址,如果你使用了虚拟机,该地址是虚拟机中Fedora9 的IP 地址,也就是直接提供NFS 服务的Linux 系统IP 地址。
这里我机器使用的IP地址是192.168.1.200。
“ip=”后面:
第一项(192.168.1.230)是目标板的临时IP(注意不要和局域网内其他IP 冲突);
第二项(192.168.1.200)是开发主机的IP;
第三项(192.168.1.200)是目标板上网关(GW)的设置;
第四项(255.255.255.0)是子网掩码;
第五项是开发主机的名字(一般无关紧要,可随便填写)
eth0 是网卡设备的名称
介绍完之后,再输入[q],进入uboot的shell界面,如下图所示,输入help,可以查看shell下的所有命令。
例如,输入bdinfo命令,可以查看单板信息:
输入printenv命令可以查询系统内部的环境变量,包括启动参数