参考:http://blog.chinaunix.net/uid-26207112-id-3332621.html

1. 正确地创建一个包含启动分区的磁盘映像

1.1 创建磁盘映像文件

首先需要对磁盘的结构有一个直观的了解,参考:http://en.wikipedia.org/wiki/Cylinder-head-sector

(Head, Cylinder, Sector)这个三元组用于在磁盘上快速地定位一个扇区(Sector)。

而且一个磁盘的容量也可以根据这三个参数的范围计算出来。

在这里,我们设置heads=16, sector=63, cylinder=100,那么这块磁盘的容量为

   1: daniel@ubuntu:~$ echo $((16*63*100*512)) bytes

   2: 51609600 bytes

大约49MB。

   1: daniel@ubuntu:~$ dd if=/dev/zero of=linux.img count=$((16*63*100))

   2: 100800+0 records in

   3: 100800+0 records out

   4: 51609600 bytes (52 MB) copied, 0.266729 s, 193 MB/s

1.2 将磁盘映像文件挂载为loop块设备

我们需要对磁盘映像文件进行块设备操作,因此需要将其挂载为loop块设备(参考:http://en.wikipedia.org/wiki/Loop_device)。

In Unix-like operating systems, a loop device, vnd (vnode disk), or lofi (loopback file interface) is a pseudo-device that makes a file accessible as a block device.

   1: daniel@ubuntu:~$ sudo losetup /dev/loop0 linux.img 

1.3 在/dev/loop0上创建启动分区

使用cfdisk分区工具,其中-s参数指定块设备的sector参数,-h参数指定块设备的磁头参数。

   1: daniel@ubuntu:~$ sudo cfdisk -h 16 -s 63 /dev/loop0

“New”按钮创建一个新的[Primary]类型的分区,在MBR分区表中只保存Primary类型的分区,因此只有Primary类型的分区能够作为启动分区。分区的大小选默认,即占据整个磁盘空间,因为我们只需要一个分区。

分完区后,将该分区设置成“Bootable”。

选择“Write”,将改动写入到目标块设备,在要求确认提示时输入yes。

选择“Quit”退出cfdisk界面。

1.4 将新创建的分区格式化成Ext4文件系统

查看新创建的分区的起始扇区号

   1: daniel@ubuntu:~$ sudo fdisk -l /dev/loop0

   2:  

   3: Disk /dev/loop0: 51 MB, 51609600 bytes

   4: 16 heads, 63 sectors/track, 100 cylinders, total 100800 sectors

   5: Units = sectors of 1 * 512 = 512 bytes

   6: Sector size (logical/physical): 512 bytes / 512 bytes

   7: I/O size (minimum/optimal): 512 bytes / 512 bytes

   8: Disk identifier: 0x00000000

   9:  

  10:       Device Boot      Start         End      Blocks   Id  System

  11: /dev/loop0p1                    100799       50368+  83  Linux

将磁盘映像文件的第64个扇区开始的区域挂载成/dev/loop1。注意,如果磁盘映像文件分配了多个分区的话,还需要使用—sizelimit设置区域大小。

   1: Setup loop device:

   2:  

   3:      losetup [{-e|-E} encryption] [-o offset] 

[--sizelimit size]

   4:              [-p pfd] [-r] {-f[--show]|loopdev} file

   1: daniel@ubuntu:~$ sudo losetup /dev/loop1 linux.img -o $((63*512))

将分区格式化为Ext4文件系统:

   1: daniel@ubuntu:~$ sudo mkfs.ext4 /dev/loop1

   2: mke2fs 1.41.14 (22-Dec-2010)

   3: Filesystem label=

   4: OS type: Linux

   5: Block size=1024 (log=0)

   6: Fragment size=1024 (log=0)

   7: Stride=0 blocks, Stripe width=0 blocks

   8: 12600 inodes, 50368 blocks

   9: 2518 blocks (5.00%) reserved for the super user

  10: First data block=1

  11: Maximum filesystem blocks=51642368

  12: 7 block groups

  13: 8192 blocks per group, 8192 fragments per group

  14: 1800 inodes per group

  15: Superblock backups stored on blocks: 

  16:     8193, 24577, 40961

  17:  

  18: Writing inode tables: done                            

  19: Creating journal (4096 blocks): done

  20: Writing superblocks and filesystem accounting information: done

  21:  

  22: This filesystem will be automatically checked every 32 mounts or

  23: 180 days, whichever comes first.  Use tune2fs -c or -i to override.

2. 安装Grub2(Boot Loader)到该磁盘映像文件中

参考:http://members.iinet.net/~herman546/p20/GRUB2%20Bash%20Commands.html

Boot Loader是加载操作系统的必要程序,其实就是一大段代码,这段代码负责将Linux内核文件从文件系统中读入到内存里,进行解压、搬移以及初始化参数的传递操作,然后将系统的控制权交给Linux内核。

Boot Loader通常分为两部分,第一部分安装到MBR的前446字节中,第二部分安装到其他的位置,通常是MBR与第一个分区之间的磁盘区域。

2.1 拷贝grub程序到目标根文件系统中的/boot目录

   1: daniel@ubuntu:~$ sudo mkdir linux

   2: daniel@ubuntu:~$ sudo mount /dev/loop1 linux

   3: daniel@ubuntu:~$ sudo mkdir linux/boot

   4: daniel@ubuntu:~$ sudo cp -r /usr/lib/grub/i386-pc/ linux/boot/grub

2.2 创建grub代码程序

   1: daniel@ubuntu:~$ sudo grub-mkimage -O i386-pc -o linux/boot/grub/core.img biosdisk part_msdos ext2

生成一个core.img, biosdisk负责读取磁盘, part_msdos负责处理MBR, ext2负责读取ext3分区.

2.3 将core.img安装到磁盘上

SYNOPSIS
grub-setup [OPTION]... DEVICE DESCRIPTION
Set up images to boot from DEVICE. DEVICE must be a GRUB device (e.g.
`(hd0,1)'). -b, --boot-image=FILE
use FILE as the boot image [default=boot.img] -c, --core-image=FILE
use FILE as the core image [default=core.img] -d, --directory=DIR
use GRUB files in the directory DIR [default=/boot/grub] -m, --device-map=FILE
use FILE as the device map [default=/boot/grub/device.map] -r, --root-device=DEV
use DEV as the root device [default=guessed]
http://man.he.net/man8/grub-setup
   1: daniel@ubuntu:~$ sudo vi linux/boot/grub/device.map

   2: (hd0) /dev/loop0

   1: daniel@ubuntu:~$ sudo grub-setup -m linux/boot/grub/device.map -d linux/boot/grub/ -r '(hd0,1)''(hd0)' /dev/loop0

If the device map file exists, the GRUB utilities (grub-probe, grub-setup, etc.) read it to map BIOS drives to OS devices. This file consists of lines like this:

(device) file

device is a drive specified in the GRUB syntax (see Device syntax), and file is an OS file, which is normally a device file.

http://www.gnu.org/software/grub/manual/html_node/Device-map.html

3. 将最小的根文件系统添加到启动分区中

可以参考:http://blog.csdn.net/deansrk/article/details/6661293

将最新的内核文件,以及/bin/sh及其依赖文件都拷贝到目标文件系统中。


如果想要制造一个更加完善的根文件系统,可以选择busybox。

参考:http://blog.chinaunix.net/uid-14720887-id-3033771.html

编译BusyBox的步骤:

3.1 配置

   1: sudo make menuconfig

选中“Busybox Settings-> Build Options-> Build Busybox as a static binary”。

3.2 编译,安装

   1: sudo make

   2: sudo make install

3.3 定制化

在_install目录下生成目标根目录结构,我们需要对该目录结构做一些修改:

3.3.1  创建子目录
   1: mkdir proc sys etc dev 

3.3.2  创建设备文件
   1: cd dev

   2: sudo mknod console c 5 1

   3: sudo mknod null c 1 3

   4:  

   5:  

3.3.3  编辑/etc/fstab
proc /proc proc defaults 0 0

sysfs /sys sysfs defaults 0 0

 

3.3.4  编辑/etc/inittab
::sysinit:/etc/init.d/rcS

console::respawn:-/bin/sh

::ctrlaltdel:/sbin/reboot

::shutdown:/bin/umount –a -r

 

3.3.5  编辑/etc/init.d/rcS,并赋予其执行权限
#!/bin/sh

mount -a

 

3.3.6  修改init文件
   1: rm linuxrc

   2: ln –sv bin/busybox init

   3:  

3.4 与Grub生成的根文件系统合并

   1: sudo cp -r busybox/_install/* linux/

4. 64位主机系统下创建Bochs可以使用的busybox根文件系统

64位系统编译出来的busybox无法被Bochs使用,因为Bochs是32位模拟器,会在内核启动后期提示:

   1: request_module: runaway loop modprobe binfmt-464c

因此需要参考:http://www.cnblogs.com/long123king/p/3562020.html

   1: sudo apt-get install libc6-dev-i386 gcc-multilib g++-multilib 

   2:  

在Makefile中添加

   1: CFLAGS += -m32

   2: LDFLAGS += -m32

   3: CPPFLAGS += -m32

   4:  

然后,再按上文3中的步骤重新编译。

 

如何制作一个可以用Bochs调试的最新内核系统盘的更多相关文章

  1. 用bochs调试自己写的系统引导代码

    1 安装和配置bochs 首先从bochs.sourceforge.net里面把BOCHS给download下来,鉴于Windows的普及,仅仅谈BOCHS在win下的使用方法,其实在其它的OS中方法 ...

  2. 用Phaser来制作一个html5游戏——flappy bird (二)

    在上一篇教程中我们完成了boot.preload.menu这三个state的制作,下面我们就要进入本游戏最核心的一个state的制作了.play这个state的代码比较多,我不会一一进行说明,只会把一 ...

  3. 利用DreamweaverCS5制作一个含有动态标题的教程

    DreamweaverCS5怎么制作一个含有动态标题?做一个网页就先要做一个标题,一个好标题会让网页让人印象深刻,有动态的标题会让网页更生动,下面我就介绍一下怎么制作一个含有动态的标题   做一个网页 ...

  4. 如何制作一个类似Tiny Wings的游戏(2) Cocos2d-x 2.1.4

    在第二篇<如何制作一个类似Tiny Wings的游戏>基础上,增加添加主角,并且使用Box2D来模拟主角移动,原文<How To Create A Game Like Tiny Wi ...

  5. iOS自定义控件教程:制作一个可重用的旋钮

    当你的APP需要一些新功能时,自定义UI控件会十分有用,尤其是这些自定义控件可以在其他APP里面很好的重用.Colin Eberhart写过一篇很棒的介绍自定义UI控件的教程.这个教程涉及的是一个继承 ...

  6. 怎样制作一个相似Tiny Wings的游戏 Cocos2d-x 2.1.4

    在第一篇<怎样使用CCRenderTexture创建动态纹理>基础上,添加�创建动态山丘,原文<How To Create A Game Like Tiny Wings with C ...

  7. 实例学习SSIS(一)--制作一个简单的ETL包

    原文:实例学习SSIS(一)--制作一个简单的ETL包 导读: 实例学习SSIS(一)--制作一个简单的ETL包 实例学习SSIS(二)--使用迭代 实例学习SSIS(三)--使用包配置 实例学习SS ...

  8. 如何制作一个类似Tiny Wings的游戏 Cocos2d-x 2.1.4

    在第一篇<如何使用CCRenderTexture创建动态纹理>基础上,增加创建动态山丘,原文<How To Create A Game Like Tiny Wings with Co ...

  9. (转)C#制作一个消息拦截器

    首先,我们先要制作一个自定义Attribute,让他可以具有上下文读取功能,所以我们这个Attribute类要同时继承Attribute和IContextAttribute. 接口IContextAt ...

随机推荐

  1. ‘’‘安装PyMouse,个人日志'''

    管理员启动CMD 1.直接pip install pymouse,成功安装, 2.安装PyHook: https://www.lfd.uci.edu/~gohlke/pythonlibs/ (向下滑动 ...

  2. [fw]拦截系统调用

    今天在ubuntu中玩了下“拦截系统调用”,记录下自己对整个实现的理解. 原理 在linux kernel中,系统调用都放在一个叫做“sys_call_table”的分配表里面,在进入一个系统调用的最 ...

  3. IntelliJ IDEA 中 Ctrl+Alt+Left/Right 失效

    开发工具:Idea OS:Window 7 在idea中使用ctrl+b跟踪进入函数之后,每次返回都不知道用什么快捷键,在idea中使用ctrl+alt+方向键首先会出现与win7屏幕方向的快捷键冲突 ...

  4. git账号失效问题解决

    linux开发机上,使用某人账号,进行代码同步.该员工离职,导致该git账号不可用. 此时需要完成3步配置: 1.生成新的公私秘钥:在~/.ssh/config中把私钥文件路径 append到文件末尾 ...

  5. differential evolution代码实例(DE算法)

    DE算法是遗传算法中一种比较流行的算法,这种算法比较简单,速度也比较快,下面给出一份示例代码 clear all; close all; clc 2 %Function to be minimized ...

  6. 解决嵌套在ScrollView中的TableView滑动手势冲突问题

    最近在迭代开发公司项目的时候遇到了一个问题,在可以左右切换标签视图的ScrollView中嵌套了两个TableView用于展示视图,感觉一切so easy的情况下,问题出现了,因为左右两个视图既可以实 ...

  7. Redis这篇就够了

    Redis 简介 Redis 优势 Redis 数据类型 string hash list set Zset 小总结 基本命令 发布订阅 简介 实例 发布订阅常用命令 事务 实例 Redis 事务命令 ...

  8. 08.Linux系统启动root密码忘记及文件系统故障问题

    问题:root用户密码忘记了,在重置root密码时,出现文件系统故障,没有root密码进不去,怎么办? Error:UNEXPECTED INCONSISTENCY;RUN fsck MANUALIY ...

  9. bzoj4987 Tree 树上背包

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4987 题解 一道还不错的题咯. 很容易发现一个结论:这 \(k\) 个点构成的一定是一个连通块 ...

  10. 如何防御DNS陷阱?黑客常用3种DNS欺骗手法

    DNS如何被利用?那么这个系统如何让用户变得脆弱?通常解析器会告诉每个DNS服务器你正在寻找哪个域名.此请求有时会包含您的完整IP地址.或者,如果不是您的完整IP地址,请求中通常会包含您的大部分IP地 ...