首页 | 社区 | 博客 | 招聘 | 文章 | 新闻 | 下载 | 读书 | 代码
亲,您未登录哦! 登录 | 注册

制作运行在内存中的Linux系统

打印文章

分享到:
  一般情况下,linux系统启动过程是,写在MBR上的bootloader加载内核,然后加载初启环境,即initrd;在initrd中,一般有个叫init或linuxrc的脚本(或ELF文件),该进程启动后,会先读取/etc/inittab下的内容,这是一个初始化表,用以确定执行/etc/rc.d下的哪个RC脚本,RC脚本执行完毕后,文件系统基本上就得到所有的硬件信息了,进而加载真正的根分区。现在要做的是——将initrd作为根分区,这样,要做的事情主要有四点:1.创建一个空间比较大的Ramdisk ,2.用busybox生成文件系统中必备的命令,用它的主要原因是占用空间小,3.添加或修改dev和etc下的文件,4.考虑添加一些应用程序,比如ssh等。 

  操作系统:SlackWare12,内核版本:2.6.21.5-smp 

  1.创建一个空间比较大的Ramdisk 

  #dd if=/dev/zero of=/tmp/ramdisk bs=1k count=92160 

  #losetup /dev/loop2 /tmp/ramdisk 

  #mkfs.ext2 /dev/loop2 

  #mount -t ext2 /dev/loop2 /mnt 

  可以向/mnt下写东西了,然后 

  #umount /mnt 

  以后修改时,可以这样用 

  #gunzip ramdisk.gz //将initrd解压 

  #mount -o loop ramdisk /mnt //挂载 

  ... ... //修改其中的内容 

  #gzip -9 ramdisk //重新压缩 

  2.用busybox生成文件系统中必备的命令 

  下载一个比较新的busybox,首先需要修改源代码,否则会在编译时出现因未采用uclibc编译而产生的错误。打开applets/applets.c文件,注释掉“ 

  #if ENABLE_STATIC && defined(__GLIBC__) && !defined(__UCLIBC__) 

  #warning Static linking against glibc produces buggy executables 

  #warning (glibc does not cope well with ld --gc-sections). 

  #warning See sources.redhat.com/bugzilla/show_bug.cgi?id=3400 

  #warning Note that glibc is unsuitable for static linking anyway. 

  #warning If you still want to do it, remove -Wl,--gc-sections 

  #warning from top-level Makefile and remove this warning. 

  #endif”这段代码。 

  执行#make menuconfig,根据网上的文章所说,主要需要注意两个地方,一是选中“将busybox编译成静态连接的可执行文件”,二是选中“不使用系统的usr目录”,另外还要留意一下,选中的默认SHELL是什么。然后执行make命令,就会在_install目录下生成一些文件,将它们拷贝到ramdisk中待用。 

  3.添加或修改dev和etc下的文件 

  在ramdisk下, 

  mkdir dev etc root usr var tmp proc mnt 

  先说说dev的, 

  可以将编译环境的dev下所有文件拷贝过去,#cp -a /dev/* ramdisk/dev ;也可以采用busybox/examples/bootfloppy下的mkdevs.sh脚本生成设备文件。 

  再说说etc下的文件,这个比较麻烦,我现在也没完全弄清楚,呵呵。我当前的办法是——将编译环境的etc下所有文件整体拷贝过去,然后用busybox/example/下的inittab覆盖ramdisk/etc下的inittab文件。这个新的inittab文件忽略了runlevel,也不需要用户登陆的用户名和密码,只需要一个rcS脚本(在busybox/examples/bootfloppy/etc中)。修改/etc/fstab内容,改为: 

  /dev/ram0 / ext3 defaults 1 1 

  devpts /dev/pts devpts gid=5,mode=620 0 0 

  proc /proc proc defaults 0 0 

  4.改写lilo 

  在lilo.conf中添加 

  image = /boot/vmlinuz 

  initrd=/boot/test_kern/ramdisk.gz 

  label = test 

  append="mem=600M ramdisk=92160 root=/dev/ram0 rw" 

  执行#lilo -v -C /etc/lilo.conf -s /boot 

  至此,Ramdisk制作完成,具备基本运行环境,加载网卡驱动后能连接网络,但是还不能ssh登陆。 

  5.考虑添加一些应用程序,比如ssh等 

  我现在的做法是,将sshd,ssh等命令和etc下的相关文件拷贝过来,缺少的库用执行ldd的方法查看,然后拷贝到lib下,dev下还有random和unrandom文件要拷贝,还有var下需要建立empty和run目录。 

  起初,在Ramdisk 上运行的系统上执行/etc/rc.d/rc.sshd start时提示“privilege separation user sshd does not exist”。问题原因是uid未知(etc的所有文件是从原编译环境拷贝的),执行passwd命令时会发生错误,提示“unknown uid 0”。解决办法是添加lib文件 

  libnss_compat.so.2 

  libnsl.so.1 

  libnss_nis.so.2 

  libnss_files.so.2 

  我又添加了bash等程序,这样/lib下有以下这些文件: 

  -rwxr-xr-x 1 root root 131484 2008-01-25 10:15 ld-linux.so.2* 

  -rwxr-xr-x 1 root root 23512 2008-01-25 10:14 libacl.so.1* 

  -rwxr-xr-x 1 root root 12324 2008-01-25 10:15 libattr.so.1* 

  -rwxr-xr-x 1 root root 1528742 2008-01-28 10:33 libc.so.6* 

  -rwxr-xr-x 1 root root 25250 2008-01-28 10:33 libcrypt.so.1* 

  -rwxr-xr-x 1 root root 13506 2008-01-28 10:33 libdl.so.2* 

  -rwxr-xr-x 1 root root 96480 2008-01-28 19:09 libnsl.so.1* 

  -rwxr-xr-x 1 root root 35494 2008-01-28 19:09 libnss_compat.so.2* 

  -rwxr-xr-x 1 root root 45552 2008-01-28 19:10 libnss_files.so.2* 

  -rwxr-xr-x 1 root root 41045 2008-01-28 19:10 libnss_nis.so.2* 

  -rwxr-xr-x 1 root root 110796 2008-01-25 10:14 libpthread.so.0* 

  -rwxr-xr-x 1 root root 77439 2008-01-28 10:30 libresolv.so.2* 

  -rwxr-xr-x 1 root root 34905 2008-01-25 10:13 librt.so.1* 

  -rwxr-xr-x 1 root root 10280 2008-01-25 12:38 libtermcap.so.2* 

  -rwxr-xr-x 1 root root 12537 2008-01-28 10:31 libutil.so.1* 

  drwxr-xr-x 3 root root 1024 2008-01-28 10:37 modules/

本栏文章均来自于互联网,版权归原作者和各发布网站所有,本站收集这些文章仅供学习参考之用。任何人都不能将这些文章用于商业或者其他目的。( Pfan.cn )

编程爱好者论坛

本栏最新文章