0、背景及目的

利用debootstrap构建一个可单独运行的镜像文件。
环境:ubuntu 16.04 64bit,虚拟机软件:vmware 12。

本文有如下假定和术语:

  • 本文使用vmware实验。
  • 根文件系统源码位于/mnt/rootfs/
  • 原系统是指原本的ubuntu系统,新系统是指用debootstrap下载的并自己添加了文件的系统。
  • 新磁盘指/dev/sdb(分区有sdb1、sdb2),sdb2为数据盘,将其格式化并挂载到/tmp/latelee
  • 如无异常,实验后期/mnt/rootfs//tmp/latelee除磁盘id、启动文件外,其它文件几乎一致。
  • 本文实验有一定风险,请先对vmware的虚拟机系统做快照。
  • 有部分步骤需要使用chroot,请一定要注意。在文中亦有标明。
  • 宿主机操作命令前带sudo表示其为root权限执行,如嫌麻烦先切换到root用户。chroot环境默认即为root。
  • 生成的文件需要通过虚拟机共享或samba共享。
  • 以上路径和名称,仅为本文采用,如读者参照,可相同,亦可更改为自己便利的方式。
  • 如果行文有磁盘大小无法对应之问题,因行文多次实验,会存在漏记,非Bug,但需要读者自行辨别。

一、构建基本环境

安装 debootstrap:

$ sudo apt-get install debootstrap

debootstrap命令格式为:

$ sudo debootstrap --arch [平台] [发行版本代号] [目录]

本文使用的命令:

$ sudo mkdir /mnt/rootfs
$ sudo debootstrap xenial /mnt/rootfs/

即安装的版本为xenial(亦即ubuntu 16.04),系统位数自动检测(64bit)。

注:在实验时,出现findutils无法下载的情况,手动下载之。

包名:findutils_4.6.0+git+20160126-2_amd64.deb
下载地址: https://packages.ubuntu.com/xenial/amd64/findutils/download

输入上述命令后,就会从网络下载相关的文件,当看到:

I: Configuring initramfs-tools...
I: Configuring ureadahead...
I: Configuring resolvconf...
I: Base system installed successfully.

即表示成功。否则重新尝试。

下面使用chroot进入/mnt/rootfs目录,并查看linux版本。本步骤亦可不做。

latelee@ubuntu:~$ cd /mnt/rootfs/
latelee@ubuntu: /mnt/rootfs$ ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
latelee@ubuntu: /mnt/rootfs$ sudo -s
[sudo] password for latelee:
root@ubuntu: /mnt/rootfs# chroot .
root@ubuntu:/# ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@ubuntu:/# cat etc/issue
Ubuntu 16.04 LTS \n \l

root@ubuntu:/# uname -a
Linux ubuntu 4.8.0-36-generic #36~16.04.1-Ubuntu SMP Sun Feb 5 09:39:57 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

二、配置

2.1 添加用户及密码

本小节切换到新系统rootfs中,即用chroot切换,因为设置的用户是新系统的,如无用户,无法使用。

# adduser latelee  // 添加用户latelee
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
        LANGUAGE = (unset),
        LC_ALL = (unset),
        LANG = "en_US.UTF-8"
    are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
Adding user `latelee' ...
Adding new group `latelee' (1000) ...
Adding new user `latelee' (1000) with group `latelee' ...
Creating home directory `/home/latelee' ...
Copying files from `/etc/skel' ...
Enter new UNIX password:  // 输入密码
Retype new UNIX password: // 再输入密码 
passwd: password updated successfully
Changing the user information for latelee
Enter the new value, or press ENTER for the default // 下面的直接回车即可
        Full Name []: 
        Room Number []: 
        Work Phone []: 
        Home Phone []: 
        Other []: 
Is the information correct? [Y/n] 

root@ubuntu:/# passwd root  // 添加root密码
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully

查看/etc/shadow看看root密码是否设置了。如设置,相应用户名后会有很长的字符串(看似乱码但有含义,此处不表)。下面是加了密码的文件:

# cat /etc/shadow
root:$6$yNNKXy5B$nstwL.zjmqc2tVNNixKfanXS8vUfDVtFLNnzgUMg7R7h/KSkio5Nn9aQF.6uunAotoPTFjgXOGrk4buCH0Dg2.:18196:0:99999:7:::
...
latelee:$6$sLcikQP5$egECjZCr1pPWjd7Nmh.LNtGICJWCffD/CTejZb6WCaptW8lurPdQ4tK5OaebL1tHN73egZyAZIiSiWpGzlLB81:18196:0:99999:7:::

做一个标志文件,方便验证:

# date > /etc/myinfo
# echo "Late Lee" >> /etc/myinfo 

2.2 安装常用工具

新构建的系统,只有常见工具,其它工具需要额外安装,如vim等,请根据需求安装,可以不安装。此小节命令需要在chroot环境中执行。

apt-get install build-essential

如果要编译内核,则要安装ncurses库:

apt-get install libncurses5-dev libncurses5

安装其它杂七杂八的:

apt-get install vim tree

2.3 添加硬盘

在VMware添加外设十分简单,在VM->Settings...->Add...中已经有很多外设可添加。这里选Hard Disk,大小自定义,但至少2GB。如图1、图2所示。
在这里插入图片描述
图1
在这里插入图片描述
图2

添加后要重启虚拟机系统才能被识别到,如无意外,新硬盘设备名为sdb。

下面格式化之。

$ sudo fdisk /dev/sdb

此处分2个区,sdb1是交换区,大小为1GB,剩下的是sdb2分区。

n 回车 回车 回车 +1GB  (第一个分区OK)
n 回车 回车 回车 回车   (第二个分区OK)
p (查看分了几个区)
w (写入分区表并退出)

格式化:

$ sudo mkswap /dev/sdb1
Setting up swapspace version 1, size = 954 MiB (1000337408 bytes)
no label, UUID=c1f47190-2158-494f-918c-941d314d716b

$ sudo mkfs.ext4 /dev/sdb2
mke2fs 1.42.13 (17-May-2015)
Creating filesystem with 279808 4k blocks and 69984 inodes
Filesystem UUID: b07cf1a8-e1fa-45ba-a1fe-e7cc8e34586b
Superblock backups stored on blocks: 
        32768, 98304, 163840, 229376

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done

查看分区uuid:

$ sudo blkid
/dev/sda1: UUID="3d474681-e5f8-468d-973a-f2ff0348a785" TYPE="ext4" PARTUUID="39cf4ae2-01"
/dev/sda5: UUID="8b9fb920-dd4f-4c4b-bf7d-9f8997ec24b1" TYPE="swap" PARTUUID="39cf4ae2-05"
/dev/sdb1: UUID="c1f47190-2158-494f-918c-941d314d716b" TYPE="swap" PARTUUID="0136d3b5-01"
/dev/sdb2: UUID="b07cf1a8-e1fa-45ba-a1fe-e7cc8e34586b" TYPE="ext4" PARTUUID="0136d3b5-02"

将前面的新系统拷贝到sdb2中(注:根据机器性能,可能较耗时)。

sudo mkdir /tmp/latelee
sudo mount /dev/sdb2 /tmp/latelee
sudo cp -a /mnt/rootfs/* /tmp/latelee

2.4 内核

直接使用宿主机上的/boot目录。拷贝:

$ sudo cp -a /boot/ /tmp/latelee

为方便,建议拷贝一份到/mnt/roofs中。

2.5 磁盘和引导文件

用chroot进入rootfs。如果在宿主上操作,可能因误操作影响原系统的文件。
修改(或新建)/etc/fstab文件,参考宿主机编写,将UUID修改为新硬盘的。(注:文件注释使用宿主机的,未修改,根据分区格式名称选择UUID)

# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
# / was on /dev/sda1 during installation
UUID=b07cf1a8-e1fa-45ba-a1fe-e7cc8e34586b  /               ext4    errors=remount-ro 0       1
# swap was on /dev/sda5 during installation
UUID=c1f47190-2158-494f-918c-941d314d716b none            swap    sw              0       0

修改(或新建)/boot/grub/grub.cfg 文件。

set default=0
set timeout=3
menuentry 'Late Lee Ubuntu' {
      set root='hd0,msdos2'
      echo "vmlinuz...."
      # linux  /boot/vmlinuz-4.8.0-36-generic root=/dev/sda2 ro console=tty0 console=ttyS0,115200n8
      linux /boot/vmlinuz-4.8.0-36-generic root=UUID=b07cf1a8-e1fa-45ba-a1fe-e7cc8e34586b ro find_preseed=/preseed.cfg auto noprompt priority=critical locale=en_US quiet splash $vt_handoff

      initrd /boot/initrd.img-4.8.0-36-generic
}

注1:grub.cfg可在宿主机基础上修改,也可自己编写。
注2:如果只有一个分区,挂载根文件“/”,则内核镜像必须使用/boo/vmlinuz路径形式,并指定为根文件系统分区的UUID,如果/boot单独一个分区,则只能使用vmlinuz形式,并指定为/boot分区的UUID。这点一定要注意。
注3:hd0,msdos2表示系统识别到的第一块硬盘的第二个分区。如从/dev/sdb启动,则启动的硬盘是第一块(哪怕还存在/dev/sda),本文根文件系统位于/dev/sdb2,所以是第二个分区。(sda和sdb是从宿主机角度描述,在系统启动时,会自动检测并重新赋设备名称)

2.6 使用原系统grub引导

安装grub:

$ sudo grub-install /dev/sdb
$ sudo update-grub
Generating grub configuration file ...
Warning: Setting GRUB_TIMEOUT to a non-zero value when GRUB_HIDDEN_TIMEOUT is set is no longer supported.
Found linux image: /boot/vmlinuz-4.8.0-36-generic
Found initrd image: /boot/initrd.img-4.8.0-36-generic
Found memtest86+ image: /boot/memtest86+.elf
Found memtest86+ image: /boot/memtest86+.bin
Found Ubuntu 16.04 LTS (16.04) on /dev/sdb2 // !!!!!
done

即在原系统上添加了sdb2的启动。重启虚拟机,如图3所示:
在这里插入图片描述
图3

可以看到,第二块磁盘已经出现在grub选项中了。选择之即可启动新的系统。

三、启动试验

本节尝试脱离原磁盘,即单独从新硬盘启动。

3.1 安装grub

安装grub:

$ sudo grub-install /dev/sdb --root-directory=/tmp/latelee
Installing for i386-pc platform.
Installation finished. No error reported.

3.2 制作镜像文件

将新磁盘全盘拷贝到镜像文件,使用dd命令拷贝可以保证磁盘分区的UUID一致性,对于批量操作而言,十分有用。

dd if=/dev/sdb of=myrootfs.img

(注:根据机器性能耗时会有差异,本次实验耗时约25分钟左右)

得到的myrootfs.img文件可以通过虚拟机软件vmware共享或samba共享将其拷贝到Windows系统,方便使用。

3.3 使用虚拟机启动镜像文件

前一小节得到了rootfs.img文件。
使用vmware重新启动原系统,启动时,按F2进入bios,选择第二块磁盘,可以启动,但依然是原系统Grub界面,失败
在vmware新建虚拟机工程(此处略),添加软盘,指定该img文件,启动之,但是失败

3.4 使用U盘启动镜像文件

先进入原系统,再插入U盘,此时Linux才能识别出U盘,否则会被Windows识别。无无意外,U盘的设备名称应该为sdc。将新磁盘或镜像文件拷贝到U盘。(注:U盘无须分区)。

dd if=myrootfs.img of=/dev/sdc
或
dd if=/dev/sdb of=/dev/sdc

(注:此操作同样耗时,经测试,约半小时)
成功后,查看磁盘分区UUID:

/dev/sdb1: UUID="c1f47190-2158-494f-918c-941d314d716b" TYPE="swap" PARTUUID="0136d3b5-01"
/dev/sdb2: UUID="b07cf1a8-e1fa-45ba-a1fe-e7cc8e34586b" TYPE="ext4" PARTUUID="0136d3b5-02"
/dev/sdc1: UUID="c1f47190-2158-494f-918c-941d314d716b" TYPE="swap" PARTUUID="0136d3b5-01"
/dev/sdc2: UUID="b07cf1a8-e1fa-45ba-a1fe-e7cc8e34586b" TYPE="ext4" PARTUUID="0136d3b5-02"

可以看到,sdb和sdc的分区、UUID完全一致。

尝试使用vmware启动U盘,但当vmware未启动之时,U盘被windows识别,当vmware启动之时,快速进入vmware界面让其识别,但为时已晚,无法达到目的。故转向物理机操作。
重新启动物理机(即台式机或笔记本电脑),进入BIOS选择U盘启动,保存退出。
从U盘启动后,出现错误:

Error: no such device: 35524fsf-dfasdfdfa-dfasdf-dfasdfdfa-dfasdf-d
Entering rescue mode...
grub rescue> 

使用ls命令依次查看grub所在分区:

grub rescue> ls
(hd0) (hd0, msdos2) (hd0,msdos1) (hd1) (hd1,msdos3) ...
grub rescue> ls (hd0,msdos1)/boot/grub  // 此分区无文件
error: unknown filesystem.
grub rescue> ls (hd0,msdos2)/boot/grub  // 此分区有文件
./ ../ gfxblacklist.txt unicode.pf2 i386-pc/ grubenv grub.cfg locale/ fonts/

经查,知道msdos2分区存在grub文件。查看启动参数:

grub rescue> set
cmdpath=(hd0)
prefix=(hd0)/boot/grub
root=hd0

可见,启动参数不正确,故无法成功引导系统。
将参数更改为前面确定的路径:

grub rescue> set root=hd0,msdos2
grub rescue> set prefix=(hd0,msdos2)/boot/grub
grub rescue> insmod normal // 可理解为“安装normal命令”
grub rescue> normal  // 后会出现grub界面

注意!grub命令行功能不强大,而且路径不能有空格,如(hd0,msdos2),逗号后不能有空格,否则无法识别
真实演示如图4所示。
在这里插入图片描述
图4

之后出现grub界面,默认有倒计时3秒,图5是暂停的图示:
在这里插入图片描述
图5

启动系统后,可输入用户名和密码,图6是查看标志文件及内核的图示:
在这里插入图片描述
图6
经验证,与前面设置的预期一致。

注:限于精力和能力,在物理机实验情况下,暂时不敢对U盘及硬盘做太多的试验,否则硬盘一旦损坏,后果不堪设想

2019.10.31:本文章实验还未算正式成功,仅做示例参考

查看mbr,即磁盘第一个扇区:

$ sudo dd if=/dev/sdb of=mbr.img bs=512 count=1
$ hexdump -C mbr.img
00000000  eb 63 90 00 00 00 00 00  00 00 00 00 00 00 00 00  |.c..............|
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000050  00 00 00 00 00 00 00 00  00 00 00 80 01 00 00 00  |................|
00000060  00 00 00 00 ff fa 90 90  f6 c2 80 74 05 f6 c2 70  |...........t...p|
00000070  74 02 b2 80 ea 79 7c 00  00 31 c0 8e d8 8e d0 bc  |t....y|..1......|
00000080  00 20 fb a0 64 7c 3c ff  74 02 88 c2 52 bb 17 04  |. ..d|<.t...R...|
00000090  f6 07 03 74 06 be 88 7d  e8 17 01 be 05 7c b4 41  |...t...}.....|.A|
000000a0  bb aa 55 cd 13 5a 52 72  3d 81 fb 55 aa 75 37 83  |..U..ZRr=..U.u7.|
000000b0  e1 01 74 32 31 c0 89 44  04 40 88 44 ff 89 44 02  |..t21..D.@.D..D.|
000000c0  c7 04 10 00 66 8b 1e 5c  7c 66 89 5c 08 66 8b 1e  |....f..\|f.\.f..|
000000d0  60 7c 66 89 5c 0c c7 44  06 00 70 b4 42 cd 13 72  |`|f.\..D..p.B..r|
000000e0  05 bb 00 70 eb 76 b4 08  cd 13 73 0d 5a 84 d2 0f  |...p.v....s.Z...|
000000f0  83 d0 00 be 93 7d e9 82  00 66 0f b6 c6 88 64 ff  |.....}...f....d.|
00000100  40 66 89 44 04 0f b6 d1  c1 e2 02 88 e8 88 f4 40  |@f.D...........@|
00000110  89 44 08 0f b6 c2 c0 e8  02 66 89 04 66 a1 60 7c  |.D.......f..f.`||
00000120  66 09 c0 75 4e 66 a1 5c  7c 66 31 d2 66 f7 34 88  |f..uNf.\|f1.f.4.|
00000130  d1 31 d2 66 f7 74 04 3b  44 08 7d 37 fe c1 88 c5  |.1.f.t.;D.}7....|
00000140  30 c0 c1 e8 02 08 c1 88  d0 5a 88 c6 bb 00 70 8e  |0........Z....p.|
00000150  c3 31 db b8 01 02 cd 13  72 1e 8c c3 60 1e b9 00  |.1......r...`...|
00000160  01 8e db 31 f6 bf 00 80  8e c6 fc f3 a5 1f 61 ff  |...1..........a.|
00000170  26 5a 7c be 8e 7d eb 03  be 9d 7d e8 34 00 be a2  |&Z|..}....}.4...|
00000180  7d e8 2e 00 cd 18 eb fe  47 52 55 42 20 00 47 65  |}.......GRUB .Ge|
00000190  6f 6d 00 48 61 72 64 20  44 69 73 6b 00 52 65 61  |om.Hard Disk.Rea|
000001a0  64 00 20 45 72 72 6f 72  0d 0a 00 bb 01 00 b4 0e  |d. Error........|
000001b0  cd 10 ac 3c 00 75 f4 c3  b5 d3 36 01 00 00 00 20  |...<.u....6.... |
000001c0  21 00 83 be 05 79 00 08  00 00 00 d0 1d 00 00 be  |!....y..........|
000001d0  06 79 83 15 50 05 00 d8  1d 00 00 28 22 00 00 00  |.y..P......("...|
000001e0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000001f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 55 aa  |..............U.|
00000200
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐