加载中…
个人资料
追梦者
追梦者
  • 博客等级:
  • 博客积分:0
  • 博客访问:213
  • 关注人气:122
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

制作可用grub引导Linux系统的磁盘映像文件 一

(2012-09-23 16:31:45)
标签:

grub

磁盘映像

img

i386

linux

分类: Linux内核分析

本文研究如何制作一个带有grub引导Linux系统的磁盘映像文件,并在磁盘映像文件中放置一个Linux bzImage,使得grub可以引导Linux,文章最后用qemu来验证磁盘映像文件的正确性。

备注:如果大家发现其中有问题欢迎留言或者email(cwsun@mail.ustc.edu.com.cn

实验平台:

系统:Linux-2.6.35.6-45.fc14.i686 GNU/Linux

虚拟机:QEMU emulator version 0.13.0(如果Fedora14系统中没有安装qemu,可用$sudo yum install qemu在线安装)

1 编译linux-2.6.38.tar.bz2

从ftp:ftp://ftp.kernel.org/pub/linux/kernel/v2.6/

下载linux-2.6.38.tar.bz2到新建的imag_dir目录,将linux-2.6.38.tar.bz2解压到img_dir目录中。

$cd image_dir

$tar xvf linux-2.6.38.tar.bz2

备注:本文使用的工作目录是img_dir。

采用i386的默认配置编译linux-2.6.38:

$make i386_defconfig

示意图如下:

 http://s14/middle/70dd1691gca5a51d0842d&690一" TITLE="制作可用grub引导Linux系统的磁盘映像文件 一" />

然后编译linux kernel:

$make

编译结果如下:

http://s11/middle/70dd1691gca5a96aea4ca&690一" TITLE="制作可用grub引导Linux系统的磁盘映像文件 一" />

2 制作用软盘引导的磁盘映像文件

需用指出的是,我们需用准备静态编译的一个应用程序init提供给linux kernel执行的后期调用。

例如编译一个输出结果为“Hello World!”的可执行文件:

//init.c

#include<stdio.h>

int main()

{

       printf(“Hello World!\n”);

       return 0;

}

该可执行文件命名为init.c

$gcc –static –o init init.c

如果静态编译源码init.c时出现:

/usr/bin/ld: cannot find -lc

collect2: ld returned 1 exit status

解决方法:

$sudo yum install glibc-static

备注:

glibc-static.i686 :C library static libraries for -static linking.

libstdc++-static.i686: Static libraries for the GNU standard C++ library

安装这两个库文件:

$sudo yum install glibc-static libstdc++-static

 

建立引导根目录映像:

使用命令:

$dd if=/dev/zero of=initrd4M.img bs=4096 count=1024

$mkfs.ext3 initrd4M.img

解释:创建一个initrd 4M.img映像,大小为4M,每个扇区4K。创建结果如下:

http://s10/middle/70dd1691gca5addfbf1c9&690一" TITLE="制作可用grub引导Linux系统的磁盘映像文件 一" />

$mkdir rootfs

$sudo mount -o loop initrd4M.img rootfs

解释:

在image_dir目录下创建一个rootfs目录,将initrd4M.img挂在到rootfs目录下。

将init拷贝到initrd4M.img的目标根目录下(因为linux启动后期会在根目录中寻找一个应用程序来运行,在根目录下提供init是一种可选方案

$cp init rootfs/

准备dev目录:

$sudo mkdir rootfs/dev

linux启动过程中会启用console设备:

$sudo mknod rootfs/dev/console c 5 1

另外需要提供一个linux根设备,我们使用ram:

$sudo mknod rootfs/dev/ram b 1 0

$sudo umount rootfs

至此,一个包含简单应用程序的根目录initrd4M.img映像就准备好。

结果如下:

http://s1/middle/70dd1691g7aa2b1180640&690一" TITLE="制作可用grub引导Linux系统的磁盘映像文件 一" />

使用命令:

$ qemu -kernel ./linux-2.6.38/arch/x86/boot/bzImage -initrd initrd4M.img -append "root=/dev/ram init=/init"

可以看到系统在qemu中启动起来,并且在启动后看到init的输出结果“Hello World!”。

示意图如下:

http://s13/middle/70dd1691gca5afa0d640c&690一" TITLE="制作可用grub引导Linux系统的磁盘映像文件 一" />

3 用busybox建立根文件系统来运行linux

上面的方案是最简单的运行建立linux映像的方法,在上面的基础上,我们更进一步:下面我们用busybox建立根文件系统来运行linux。

我们在上面建立的initrd4M.img中建立根文件系统:

下载busybox-1.19.4.tar.bz2源码到image_dir 目录中。

$cd image_dir

$tar xvf busybox-1.19.4.tar.bz2

我们在busebox缺省编译的基础上,稍作修改

$make defconfig

$make menuconfig

修改如下配置:

设置busybox settings–>build options–>build busybox

              as a static binary(no share libs)

示意图:

http://s3/middle/70dd1691gca5afe840ec2&690一" TITLE="制作可用grub引导Linux系统的磁盘映像文件 一" />

设置busybox settings> installation options as soft-links

示意图如下:

http://s13/middle/70dd1691gca5b03cea58c&690一" TITLE="制作可用grub引导Linux系统的磁盘映像文件 一" />

接着编译busybox,产生根目录印象

$make

接着将编译的根目录映像安装到myinitrd4M.img映像文件中:

我们使用前面生成的initrd4M.img,将initrd4M.img挂载到rootfs目录下:

$sudo mount -o loop initrd4M.img rootfs

在busybox-1.19.4下,将编译生成的根目录映像安装到rootfs目录中(即安装到initrd4M.img的根目录中):

$cd busybox-1.19.4

$sudo make CONFIG_PREFIX=../rootfs/ install

卸载initrd4M.img映像:

$sudo umount rootfs

运行:

$ qemu -kernel ./linux-2.6.38/arch/x86/boot/bzImage -initrd initrd4M.img -append "root=/dev/ram init=/bin/sh"

此时可以进入busybox提供的shell环境,示意图如下:

http://s12/middle/70dd1691g7aa2b46e67bb&690一" TITLE="制作可用grub引导Linux系统的磁盘映像文件 一" />

如上图所示,进入shell后,我们可以动态加载运行init!

4 制作带grub启动的磁盘映像

待续。。。。。。。

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有