2012年6月28日星期四

在虚拟磁盘映像上安装 ArchLinux

如果你是一个疯狂的 OS 爱好者,你可能硬盘里面安装了十几个 Linux 发行版,一定要分十几个区么?下面介绍如何在虚拟磁盘镜像上安装 ArchLinux。
在开始之前,强烈建议先阅读官方的安装指南
首先,用 ArchLinux 的安装光盘开机(不管你是用光盘还是U盘,或者是 GRUB 链式引导,只要开了就行)。如果你用的是2012年6月4日以后的安装光盘,需要先初始化软件包验证密钥,执行下列命令即可:
pacman-key --init
pacman-key --populate archlinux #一路敲 y,如果卡住不动,你可以晃晃鼠标消磨时间(顺便给 gpg 提供随机种子)

然后就可以开始了。
  1. 创建镜像
    先挂载上 host 镜像的盘(用 Windows 的估计都会选 NTFS 的),这里我们举例将第一磁盘第五分区作为 host 盘,采用 NTFS-3G 来负责挂载,其他格式的将 ntfs-3g 换成 mount 即可。
    mkdir /host
    ntfs-3g /dev/sda5 /host
    然后创建镜像,这里用 ext4 格式,大小为 8G,放在 diskimg 目录下,自己根据需要修改。
    truncate -s 8G /host/diskimg/archlinux.img
    mkfs -t ext4 -F /host/diskimg/archlinux.img
    modprobe loop #如果你没有用官方的安装盘,需要这行
    mount -o loop /host/diskimg/archlinux.img /mnt
  2. 准备 pacman
    mkdir -p /mnt/var/lib/pacman
    编辑 /etc/pacman.d/mirrorlist,选择自己喜欢的镜像,把它复制下来放在第一行。
    nano /etc/pacman.d/mirrorlist #当然如果你擅长 Vi,也可以用 vi
    然后同步数据库(别忘了配置网络)
    pacman -Sy
    pacman -Sy -r /mnt #顺便也把新系统的数据库同步了
  3. 安装基础系统
    pacman -Sr /mnt base ntfs-3g net-tools wireless_tools #你可能还想安装一下别的,比如说网络组件
    然后有一点耐心,一共80多兆,下载完后自动安装。其中安装 linux 包的时候会出现问题,等一会我们再弄。
  4. 配置系统
    nano /mnt/etc/rc.conf
    nano /mnt/etc/mkinitcpio.conf
    怎么配置不用我说了吧,指南上面有。
  5. 配置引导参数和引导钩子
    先将 /boot 拷出来
    mv /mnt/boot /host/diskimg/archboot
    ln -s /host/diskimg/archboot /mnt/boot
    然后是关键的一步
    依次创建这些文件(斜体字部分是根据自己的情况修改的):

    /mnt/usr/lib/initcpio/hooks/looproot
    # vim:set ft=sh:
    run_hook ()
    {
            # Now mount the host filesystem
            mkdir /host
            # mount -t ntfs /dev/sda5 /host
            ntfs-3g /dev/sda5 /host
    
            # And the loop filesystem
            losetup /dev/loop0 /host/diskimg/archlinux.img
            mount -t ext4 /host/diskimg/archlinux.img /new_root
            mount --bind /host /new_root/host
    }
    
    /mnt/usr/lib/initcpio/install/looproot
    #!/bin/bash
    
    build() {
        SCRIPT="looproot"
    }
    
    help() {
        cat <<HELPEOF
    HELPEOF
    }
    
    # vim: set ft=sh ts=4 sw=4 et:
    
    /mnt/etc/rc.d/functions.d/omitntfs
    #!/bin/sh
    
    omitntfs() {
        sync
        add_omit_pids $(fuser /dev/sda5 2>/dev/null | awk '-F ' '{ print $1 }')
    }
    
    # remove fuseblk from the original NETFS variable
    NETFS="nfs,nfs4,smbfs,cifs,codafs,ncpfs,shfs,fuse,glusterfs,davfs,fuse.glusterfs"
    
    add_hook shutdown_prekillall omitntfs
    add_hook single_prekillall omitntfs
    
    修改 /mnt/etc/mkinitcpio.conf
    MODULES 里面加上 loop fuse
    BINARIES 里面加上 /usr/bin/ntfs-3g(如果你不用 NTFS,并且挂载时需要辅助程序的,加进来)
    HOOKS 最后加上 looproot
    修改 /mnt/etc/fstab
    # 
    # /etc/fstab: static file system information
    #
    # <file system> <dir>   <type>  <options>       <dump>  <pass>
    /dev/loop0      /       ext4    loop            0       1
    /dev/sda5       /host   ntfs    defaults        0       0
    
    创建目录 /mnt/host
  6. Chroot 进新系统
    for i in dev proc sys host; do mount --bind /$i /mnt/$i; done
    modprobe dm-mod #如果你要安装 GRUB 的话需要这行
    chroot /mnt
    passwd #先给 root 设置个密码
  7. 创建启动内存盘
    mkinitcpio -p linux
  8. 安装引导器(谨慎!一定要按照自己的情况来更改参数以免发生意外!
    mkdir /host/boot
    grub-install --target i386-pc --boot-directory /host/boot /dev/sda
    ln -s /host/boot/grub /boot/grub
    grub-mkconfig -o /host/boot/grub/grub.cfg
    最后还有一点要声明的是,要在内核启动选项后面加上 root=/dev/loop0似乎不加也行,但我不敢保证,如果有人成功了就留言通知我一声。
  9. 重新启动
    exit
    umount /mnt/dev /mnt/proc /mnt/sys /mnt/host /mnt /host
    reboot
  10. 继续定制系统
    现在开机,启动过程中会提示错误,然后掉进紧急 shell 当中,不要慌,因为我们 hook 了开机流程,导致自带的脚本执行出错。直接敲 exit 或者按快捷键 ^D 就行了。以后每一次开机都会提示错误,网络上能找到避免的方法,但是我不建议,因为每一次 mkinitcpio 升级之后都会还原。
    这时候你已经登入了新的系统,用 root 登录,密码你前面已经设置过了。

    登录进去之后干什么?这你还用问?