📄 655.html
字号:
background="images/back.gif" tppabs="http://www.linuxhero.com/docs/images/back.gif" border=0>
<TBODY>
<TR>
<TD vAlign=top width="80%">
<DIV align=center>
<FORM action="search.html" tppabs="http://www.linuxhero.com/docs/search.html" method=get>
</FORM>
<TABLE cellSpacing=0 cellPadding=0 width="95%"
border=0><TBODY>
<TR>
<TD background="images/bgi.gif" tppabs="http://www.linuxhero.com/docs/images/bgi.gif"
height=30></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=3 width="95%"
align=center border=0>
<TBODY>
<TR>
<TD>
<TABLE cellSpacing=0 cellPadding=3 width="100%"
border=0>
<TBODY>
<TR>
<TD vAlign=top>
<p><FONT class=normalfont><B><font color=blue>自己定制软盘上的Linux系统</font></B></FONT><BR><FONT class=smallfont color=#ff9900>2004-04-23 15:18 pm</FONT><BR><FONT class=normalfont>作者:作者<br>来自:Linux知识宝库<br>联系方式:无名<br><br>一.前言<br>
<br>
嵌入式Linux是由一个几百KB的Linux内核和一个根据需要制定的文件系统所构成了, 由于Linux是开放源代码的操作系统,所以在嵌入式领域有着非常广阔的前景,并已经广泛应用在许多手机、PDA、MP3播放器等许多电子产品中。本文将介绍一种两张软盘上的Linux系统,它可以当作系统应急修复盘、路由器或防火墙等许多地方,通过对它的研究,也可以加深对嵌入式系统的理解。<br>
<br>
二.Linux启动过程<br>
<br>
所有的PC机在加电之后,BIOS会寻找到启动盘第一个扇区,并将其复制到RAM中来执行它,对于两种不同的启动方式,这个扇区通常含有两种不同的代码:引导程序(比如Lilo或Grub等)的代码,引导程序会帮助定位内核的位置。内核的代码,这通常是从软盘启动时使用的引导的方式。对于前者,通常需要内核支持initrd。如果是后者,使用的Boot Loader就是arch/i386/boot/bootsect.S。当内核被编译的时候,这段执行代码就被链接到内核image的最开始的地方。这样很容易就能只要把内核复制到起始位置为第一个扇区的软盘上就能得到可自启动的软盘。内核会初始化设备驱动和内部的数据结构,之后它会到一个特定的位置 ――Ramdisk Word来获得根文件系统的位置。内核必须知道去那里寻找这个根文件系统,否则它将停机。<br>
<br>
在使用软盘启动的方式时,内核可以把一个压缩的文件系统释放到RAM中,称之为Ramdisk,这是一个内存区域,但内核会把它当作磁盘一样使用。<br>
<br>
本文中介绍的例子使用Grub做为引导程序,并使用initrd来辅助Linux的启动。两张软盘分别命名为bootldr盘和rootfs盘,在 bootldr盘中内容为grub、内核、initrd,rootfs盘中是压缩过的根文件系统。系统启动时bootldr盘的Grub定位并执行内核,然后内核解开initrd,并执行linuxrc文件,这个文件负责提示用户更换rootfs盘并将其中内容解压至内存中,然后执行刚刚解压的init继续启动过程。<br>
<br>
为了方便理解这个例子,先介绍目录结构如下:<br>
<br>
/home/papaya<br>
├─bootldr/<br>
│ ├─grub/<br>
│ ├─kernel/<br>
│ │ ├─images/<br>
│ │ └─linux-2.4.21/<br>
│ └─initrd/<br>
│ ├─mkinitrd.sh<br>
│ ├─local/<br>
│ └─ramdisk/<br>
├─rootfs/<br>
│ ├─mkrootfs.sh<br>
│ ├─ramdisk/<br>
│ └─local/<br>
└─lib/<br>
<br>
<br>
<br>
三.定制Grub引导程序<br>
<br>
插入一张软盘,然后将其格式化,然后加载到/mnt/floppy<br>
<br>
#mke2fs /dev/fd0<br>
#mount -t ext2 /dev/fd0 /mnt/floppy -o loop<br>
在其中创建/boot/grub目录<br>
#mkdir -p /mnt/floppy/boot/grub<br>
<br>
<br>
<br>
将系统中/boot/grub下的device.map, stage1, stage2 复制到/mnt/floppy/boot/grub中,然后在/mnt/floppy/boot/grub目录下创建grub.conf文件:<br>
<br>
default=0<br>
timeout=10<br>
title Floppy Linux<br>
kernel (fd0)/bzImage root=/dev/ram0 <br>
initrd (fd0)/initrd.gz<br>
<br>
<br>
<br>
然后创建一个链接<br>
<br>
#ln -s grub.conf menu.lst<br>
<br>
<br>
<br>
执行<br>
<br>
/sbin/grub --batch --device-map=/dev/null <<EOF<br>
device (fd0) /dev/fd0<br>
root (fd0)<br>
setup (fd0)<br>
quit<br>
EOF<br>
<br>
<br>
<br>
这样grub就被安装到bootldr盘上了。<br>
<br>
四.定制Linux内核<br>
<br>
由于软盘大小的限制,内核应尽可能只包含必要的一些支持,对于本文中的例子一定要选上initrd支持。比如如果做为系统修复盘的话,必要的支持包括: IDE,PCI,和需要的文件系统类型等等就可以了,而没有必要网络支持,当然,如果做为路由器或者防火墙的话,网络支持是必要的,而其他的这可相应的删除掉。<br>
<br>
#make [xconfig | menuconfig | config]<br>
#make bzImage<br>
<br>
<br>
<br>
如果添加了模块的支持,还需要<br>
<br>
#make modules<br>
<br>
<br>
<br>
之后就得到了内核镜像bzImage。如果bzImage的大小超出了软盘的限制,就需要重新再来配置一下。将编译好的bzImage放到bootldr盘的根目录下,如果把bzImage改了名字,要注意与grub.conf中的名字一致。<br>
<br>
五.制定initrd<br>
<br>
在initrd/local目录下建立bin, dev, etc, lib, proc, sysroot, usr目录。其中dev目录下包括必要的设备文件,比如tty, ram, console等等, bin中必要的可执行文件有bzip2, chroot, cp, cpio, dd, echo, mount, pivot_root, readkey, sh, test等。Busybox提供了其中大部分。 bzip2, dd, cpio用来解压缩第二张软盘上的内容,chroot, pivot_root用来转换根目录。<br>
<br>
编辑initrd/local/linuxrc文件:<br>
<br>
#!/bin/sh<br>
<br>
<br>
<br>
把sysroot目录mount到一块内存上,并建立tmpfs文件系统。<br>
<br>
echo "Mounting new root filsystem ..."<br>
mount tmpfs /sysroot -t tmpfs<br>
cd /sysroot<br>
<br>
<br>
<br>
下面的readkey是一个很简单的程序,当启动过程执行到这里的时候暂停,等待换入第二章软盘,然后接受任意键输入继续执行启动过程。这个小程序读者可以自己实现,要注意的是最好使用静态链接。<br>
<br>
echo " "<br>
echo -en "Insert the second disk and press ANY key..."<br>
readkey > /dev/null<br>
echo " "<br>
<br>
<br>
<br>
将第二章软盘上的内容解压到sysroot目录(内存)中。<br>
<br>
echo "Loading root-archive from floppy ..."<br>
dd if=/dev/fd0 bs=1k | bzip2 -d | cpio -idv<br>
<br>
<br>
<br>
下面将initrd中的文件copy到sysroot/bin目录下,这样可以把根文件系统中一部分内容放到initrd(第一张软盘)中,因为软盘容量有限,当第一张软盘空间有剩余,而第二章软盘空间紧张的时候这会非常有用。<br>
<br>
echo "Copying:"<br>
for file in bzip2 chroot cp cpio echo readkey; do<br>
echo -en " "; echo -n $file<br>
cp /bin/$file ./bin/$file<br>
done<br>
<br>
<br>
<br>
下面将/目录设定为当前目录,即sysroot,并执行刚刚从rootfs盘中解压出来的init。<br>
<br>
echo " "<br>
echo "Pivoting / ..."<br>
pivot_root . mnt/initrd<br>
<br>
echo "Starting init process..."<br>
exec chroot . /sbin/init <dev/console >/dev/console 2>&1<br>
<br>
echo -en"Something went wrong ..."<br>
/bin/sh || /mnt/initrd/bin/sh<br>
<br>
<br>
<br>
当initrd所有必须的文件都放到bootldr/initrd/local目录下之后,就可以执行bootldr/initrd/mkinitrd.sh来创建initrd镜像文件。mkinitrd.sh的内容为:<br>
<br>
#!/bin/sh<br>
mount -t ext2 /dev/fd0 /mnt/floppy<br>
rm -f /mnt/floppy/initrd.gz<br>
rm -f initrd.gz<br>
<br>
<br>
<br>
取4M大小的内存块格式化为ext2格式,并将其mount到bootldr/initrd/ramdisk上。<br>
<br>
dd if=/dev/zero of=/dev/ram9 bs=1k count=4096<br>
mke2fs /dev/ram9<br>
mount -t ext2 /dev/ram9 ramdisk/<br>
<br>
<br>
<br>
把local中的文件复制到ramdisk目录中,也就是那块内存中。<br>
<br>
cp -R local/* ramdisk/<br>
umount ramdisk<br>
<br>
<br>
<br>
将内存中的内容压缩为initrd.gz,并复制到bootldr盘中<br>
<br>
dd if=/dev/ram9 bs=1k | gzip -v9 > initrd.gz<br>
cp initrd.gz /mnt/floppy/<br>
umount /mnt/floppy<br>
<br>
<br>
<br>
这样,bootldr盘就完成了。<br>
<br>
六.定制根文件系统<br>
<br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -