梳理一些Linux知识( by quqi99 )

梳理一些Linux知识( by quqi99 )

作者:张华  发表于:2013-09-22
版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明

( http://blog.csdn.net/quqi99 )

本文是一些使用Linux方面的高度概括,除了看Linux的代码以外,熟练用Linux估计也就是这些内容了,当然,可以还要包括一些Linux内核的调试方面的内容。本文包括:
Linux启动过程;
怎么做根文件系统镜像,是通过交叉编译链从头编译,还是从已有的发行版制作;
根文件系统镜像做完之后,怎么做内存根文件系统initrd或initramfs;
两种根文件系统准备好之后,怎么定制Linux内核;
两种根文件系统和定制的Linux内核准备好之后,如果加上Bootloader (GRUB)做成可引导的,再结合两种工具(压缩块设备的工具,将块设备转换成光盘iso设备的工具)制作成可引导的iso文件;
技术都是相通的,虽然从来没有做过嵌入式Linux,也将通过类比从理论层面想象ARM平台上嵌入式Linux的启动过程;

1,BIOS,在PC体系中,机器加电启动后,CPU会加载一小段汇编写的固件程序,叫BIOS,BIOS会检测硬件,收集硬件信息等等,然后将控制权交给硬盘MBR中的Bootloader程序。(我相信ARM平台上应该有类似于BIOS的东西,可能叫BIOS这个名字,也可能叫别的名字)。
2,Bootloader,硬盘的头512个节字叫MBR用于存储Bootloader程序,在PC平台有我们熟悉的LILO或GRUB等(在ARM平台上也应该有类似的Bootloader,可能不是GRUB,但我相信开源世界已经为我们做好了类似的东西,需要我们google之)。并且,Grub可以直接存储在硬盘的头512字节的MBR中,
在硬盘的每个分区的头512个节字中依然可以存储它,这也是为什么每块分区都能安装一个操作系统支持双系统多系统的原因。
3,Grub会引导内核,例如下列配置GRUB引导第一块硬盘(hd0)上的/dev/sda9分区的Linux内核(vmlinuz-3.8.0-rc5),同时,也指明了一个initrd (initrd-linux3.8.0-rc5.img)
  grub> root (hd0,msdos9)
  grub> kernel /boot/vmlinuz-3.8.0-rc5 ro root=/dev/sda9 acpi=off
  grub> initrd /boot/initrd-linux3.8.0-rc5.img
  grub> boot
4,内核与两个根文件系统的启动过程,Linux系统中有除了内核(主要用于对文件,进程等资源进行管理)外一般还有两个根文件系统,一个运行在内存中(initrd或者initramfs),一个存储在硬盘中(如openstack镜像)。运行在内存中的根文件系统有两种实现,一种是上面提到的initrd,如果上面grub指定了initrd,内核在启动时就会加载它到内存的一个区域运行做一些初始化的工作,如想要在后面加载硬盘里的根文件系统的话肯定得先初始化硬盘驱动啊,但是initrd的大小不能大于内核指定的内存大小,所以为了克服这个问题,内核自带了一个空的根文件系统叫initramfs,内核启动后除了mount硬盘的根文件外,它也会mount到rootfs,由于rootfs是内存的ramfs文件系统的一个实例,所以initramfs的大小不像initrd那样受指定内存大小限制,同时,由于它mount到了rootfs之间它也是常驻内存的(initrd在完成它的使命之后内核会收回它即用的内存空间)。不管是initrd还是镜像,它们都是根文件系统,也就都有名为init的可执行文件,内核加载initrd时,就会把initrd的init启动做为第一个进程,initrd的init就会做一些初始化工作如加载硬盘驱动,完事之后通过exec命令运行硬盘根文件系统里的init,由于exec的特点是子进程会完全替换父进程的进程空间,所以这样也就完全了根文件系统的切换。
5,根文件系统镜像如何做成可引导的,由上面的原理,我们知道,镜像就是一个带有init脚本的根文件系统,所以它只要是linux内核可以识别的文件格式即可(如EXT4等),所以虚机文件系统(raw,qcow2)做成内核用到的镜像需要转换成EXT4等文件系统格式。
 另外,根文件系统镜像由于存储在硬盘中,肯定也是一个块设备,如果通过loop设备模拟的文件系统镜像是可以直接通过dd命令拷贝到硬盘(/dev/sda)就能直接用的。
 如果要将它制作成光盘的话,显然还需要加上引导程序GRUB,且内核也应该是定制支持iso9006光盘驱动的内核,将根文件系统的镜像+GRUB+定制的内核通过“压缩块分区”(我没有实际做过,不知道叫什么名字,但通过原理分析我相信谷歌一下了肯定有这样的工具)的工具压缩成一个单文件,最后通过
制作光盘(因为光盘不是块设备,肯定不能使用dd命令,应该有针对光盘的专用命令,同样,我不知道叫什么,搜索一下肯定有)的工具把它做成iso文件即可。
6,现在的问题就是根文件镜像是怎么做的问题。有两种方法,一种是通过交叉编译工具链交叉编译,交叉编译工具链就是在宿主机上编译出可以支持其他平台(如其他PC平台,或者ARM平台)的gcc(C,C++编译器), glibc(C程序库), binutils(汇编和链接工具),gdb(调试工具),大家知道,linux上源码安装程序时依赖问题繁多,再加上宿主平台和目标平台差异的问题,我没实际做过但我相信估计会遇到很多具体的细节问题,要求你对gcc等这些编译或makefile知识少不了。然后可以在宿主机上随便建一个目录且将一个块设备mount在这个目录上,在这目录在建立根文件系统,将这个目录chroot之后就可以利用之前的交叉编译工具安装目标平台的一系列软件,这样做出来的就镜像。但这种方式很麻烦,我觉得只有两种场景有用,一是需要为新的CPU类型准备linux系统,二是需要减小linux发行版的体积。对于第一个需求必须这样做,对于第二个减小体积我相信可以直接使用某些小的linux发行版来做,如meego等。从理论上,更有可能直接将你正在使用的linux的根文件系统拷贝出来通过上面的一步结合启动分区做成ISO。

你可能感兴趣的:(梳理一些Linux知识( by quqi99 ))