把dubuntu安装至移动硬盘、并可在不同电脑上启动、运行的方法

Ubuntu各种衍生版本
头像
ptptptptptpt
帖子: 3711
注册时间: 2006-09-19 18:16

把dubuntu安装至移动硬盘、并可在不同电脑上启动、运行的方法

#1

帖子 ptptptptptpt » 2006-09-19 18:25

很早就有这样的想法,也学习了sir论坛savagePig兄的帖子“最简单的制作从USB启动的系统的方法”,获益良多,但发现用某些版本的内核时

,在有sata硬盘的机子上,会把移动硬盘认成sdb,而没有sata硬盘时就会认成sda,这样在不同的机子上有可能需要修改GRUB菜单中的

“root=/dev/sd**”项才能启动;另外为了应对不同的显卡,要用VESA驱动,不但性能低(看片不大爽),而且在某些显卡上(如i810)只能

用640*480的分辨率,这样一来还得手动修改显卡配置文件。不是很完美。
于是想到live cd能很好地识别硬件,能否利用一下呢?苦于不知如何下手。这时无意中看到了ubuntu中文论坛上gnix_oag兄的帖子,受到启发

,便拿dubuntu来试验,从中学习了gnix_oag兄和lvjinhua兄的脚本,几经摸索,终于感觉比较成熟了,拿出来请高人们指教。

(本文适合有一定linux经验,熟悉系统安装、grub使用的朋友)


第一步:把dubuntu安装到移动硬盘上

1.到www.dubuntu.com下载dubuntu的第一张cd:dubuntu-6.06-livecd-i386.iso。
2.光盘里有个hd_boot-686文件夹,按照里面的readme说明,可以把iso从硬盘直接引导起来,不用刻盘。
3.引导起来后,运行桌面上的“DUBUNTU简易安装程序”,按照提示安装到移动硬盘(假设安装到第一分区,下文均按此假设来描述;当然也可

以先安装到本地硬盘上,等做好设置后再拷到移动硬盘上)。


第二步:修改initrd文件

这里是关键了。我们知道此时系统的grub菜单里会有类似下面的内容:

代码: 全选

title   dubuntu
root    (hd*,0)
kernel  /boot/vmlinuz-2.6.15-23-686 root=/dev/sda1 ro splash 
initrd  /boot/initrd.img-2.6.15-23-686
也就是说grub通过initrd.img-2.6.15-23-686把系统引导起来(原理参看 “ LinuxSir.Org > Linux 综合讨论区 —— LinuxSir.Org > Linux

基础建设讨论专版 > initrd 有什麼用?[附原理详解] ”)。
其实这个initrd.img-2.6.15-23-686文件里包含有3种启动方式:live cd启动方式、本地启动、网络启动。启动时选用哪一种,是由grub菜单

和initrd.img-2.6.15-23-686里面的脚本来控制的。上面的写法就是指定了由本地启动。而我们的目的是要用live cd方式启动,这样就可以检

测硬件;不过以live cd方式启动后,对系统所作的设置是无法保存的,重启后又恢复了最初的样子,所以我们要对initrd.img-2.6.15-23-686

作些修改。

启动到刚才装好的系统里(在其它合适的系统里操作也可以,而我自己是在dubuntu里做的,所以就这样来描述了),将/boot/initrd.img-

2.6.15-23-686复制一份到桌面,改名为initrd.img-2.6.15-23-686.gz,双击,将会自动由解压软件打开,里面是一个cpio格式的包文件,将

它解压缩到某文件夹如:/home/dubuntu/123。
打开终端,进入该目录 cd /home/dubuntu/123 ,运行命令 cpio -iF initrd.img-2.6.15-23-686,解出包里的内容;打开/home/dubuntu/123

文件夹,删除initrd.img-2.6.15-23-686,并修改以下文件:


1. ……/123/scripts/casper 的内容换成如下:

代码: 全选

#!/bin/sh
# set -e

mountpoint=/sys_image
mkdir -p $mountpoint

rootdev=


[ -f /etc/casper.conf ] && . /etc/casper.conf

export  rootdev


subdevices() {
    sysblock=$1
    r=""
    for dev in "${sysblock}" "${sysblock}"/*; do
        if [ -e "${dev}/dev" ]; then
            r="${r} ${dev}"
        fi
    done
    echo ${r}
}


sys2dev() {
    sysdev=${1#/sys}
    echo "/dev/$(udevinfo -q name -p ${sysdev} 2>/dev/null|| echo ${sysdev##*/})"
}

get_fstype() {
    local FSTYPE
    local FSSIZE
    eval $(fstype < $1)
    if [ "$FSTYPE" != "unknown" ]; then
        echo $FSTYPE
        return 0
    fi
    /lib/udev/vol_id -t $1 2>/dev/null
}


find_system_partition() {
        for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -v loop | grep -v ram); do
                for dev in $(subdevices "${sysblock}"); do
                    devname=$(sys2dev "${dev}")
                    fstype=$(get_fstype "${devname}")
                    case ${fstype} in
                        ext2|ext3|reiserfs)
                            mount -t ${fstype} "${devname}" $mountpoint || continue
                      if [ -e "$mountpoint/.mobile_system" ]; then
                         umount $mountpoint
                         echo "$devname"
                         return 0
                     else
                         umount $mountpoint
                     fi
 						;;
                    esac
                done
        done
        return 1

}   


set_usplash_timeout() {
    if [ -x /sbin/usplash_write ]; then
        /sbin/usplash_write "TIMEOUT 120"
    fi
}

mountroot() {
    exec 6>&1
    exec 7>&2
    exec > casper.log
    exec 2>&1

    set_usplash_timeout
    [ "$quiet" != "y" ] && log_begin_msg "Running /scripts/casper-premount"
    run_scripts /scripts/casper-premount
    [ "$quiet" != "y" ] && log_end_msg

    # Needed here too because some things (*cough* udev *cough*)
    # changes the timeout

    set_usplash_timeout

log_begin_msg "finding system partition"
    for i in 1 2 3 4 5 6; do
        sys_partition=$(find_system_partition)
        if [ "${sys_partition}" ]; then
            break
        fi
        sleep 2
    done
    if [ "$?" -gt 0 ]; then
        panic "Unable to find a partition containing a system"
    fi
log_begin_msg "${sys_partition}"
log_end_msg

    rootdev="${sys_partition}"

    mount -t $(get_fstype "${sys_partition}") "$sys_partition" "$rootmnt"


    log_end_msg

    maybe_break casper-bottom
    [ "$quiet" != "y" ] && log_begin_msg "Running /scripts/casper-bottom"

    PATH=/root/usr/bin:/root/usr/sbin:/root/bin:/root/sbin:$PATH run_scripts /scripts/casper-bottom
    [ "$quiet" != "y" ] && log_end_msg

    exec 1>&6 6>&-
    exec 2>&7 7>&-
    cp casper.log "${rootmnt}/var/log/"
}



2. ……123/lib/casper/shutdown 后面一部分内容注释掉或删除

代码: 全选

#eject -p -m /cdrom >/dev/null 2>&1

# XXX - i18n
#echo -n "Please remove the disc, close the tray (if any) and press ENTER: "
#if [ -x /sbin/usplash_write ]; then
#    /sbin/usplash_write "TIMEOUT 0"
#    /sbin/usplash_write "TEXT Please remove the disc, close the tray (if any)"
#    /sbin/usplash_write "TEXT and press ENTER to continue"
#fi

#read x < /dev/console

exit 0
注意最后一句 exit 0 得留着!


3. 删除 ……123/scripts/casper-bottom 中无用的脚本,改12fstab

这里的脚本就是用来检测、配置硬件的,经试验,留下8个即可:
12fstab 20xconfig 23networking 31disable_update_notifier
13swap 22gnome_panel_data 30accessibility 32disable_hibernation

为了完美起见,12fstab最后部分可以改一下,不改好像问题也不大

代码: 全选

cat > $FSTAB <<EOF  
# unionfs / unionfs rw 0 0
$rootdev / $(get_fstype "${rootdev}") rw 0 0
tmpfs /tmp tmpfs nosuid,nodev 0 0
EOF

rm -f /root/etc/rcS.d/S10checkroot.sh

log_end_msg
OK!这样就改好了,可以攒起来了。还是打开终端进入 /home/dubuntu/123 目录,运行命令

find . | cpio -L -o -H newc | gzip -9 > ../initrd.686m.gz

等命令执行完,在/home/dubuntu 文件夹里就会出现我们需要的 initrd.686m.gz 文件! 把它拷到 /boot 里备用。




第三布:修改GRUB菜单

以移动硬盘第一分区作为root,把grub安装到移动硬盘上;然后修改grub菜单 /boot/grub/menu.lst ,加上如下内容:

代码: 全选

title   Dubuntu 686m
kernel  (hd0,0)/boot/vmlinuz-2.6.15-23-686 boot=casper ramdisk_size=1048576 root=/dev/ram rw splash 
initrd  (hd0,0)/boot/initrd.686m.gz
启动到grub菜单时选它就行。

OK!搞定了!洪哥我们动手吧!NO NO NO,别性急,千万别忘了最后一步──



第四步:创建记号文件

在移动硬盘第一分区──也就是系统所在的分区──的根目录下创建一个文件,命名为 .mobile_system ,用它来标记系统所在的分区。

现在完工了!重启电脑进入BIOS设为从移动硬盘启动,试试能行不?
头像
oneleaf
论坛管理员
帖子: 10441
注册时间: 2005-03-27 0:06
系统: Ubuntu 12.04

#2

帖子 oneleaf » 2006-09-19 20:04

现在fstab支持uuid的挂载,edgy中就开始使用uuid来处理fstab,如果grub可以也如此,就没有这么麻烦了。
头像
gnix_oag
帖子: 1994
注册时间: 2005-05-19 18:38
来自: 湖南永州
联系:

#3

帖子 gnix_oag » 2006-09-19 22:19

启动时选用哪一种,是由grub菜单

和initrd.img-2.6.15-23-686里面的脚本来控制的
是由引导参数控制的

boot=casper 从光盘起动
boot=local 从本地起动
boot=nfs 从网络起动
boot=自己加入的文件 用自己的方法起动.
头像
gnix_oag
帖子: 1994
注册时间: 2005-05-19 18:38
来自: 湖南永州
联系:

#4

帖子 gnix_oag » 2006-09-19 22:22

不过以live cd方式启动后,对系统所作的设置是无法保存的,重启后又恢复了最初的样子,所以我们要对initrd.img-2.6.15-23-686

作些修改。
你可以看看 viewtopic.php?t=21688&highlight=

可以保存的

:D :D
头像
ptptptptptpt
帖子: 3711
注册时间: 2006-09-19 18:16

高星兄我就是学的你方法 :)

#5

帖子 ptptptptptpt » 2006-09-21 9:47

一开始我也是照你介绍的那样做的,而且那样有个好处就是,可以随时把系统轻易地恢复到最初状态,很有吸引力!
后来看到有些文章说UNIONFS是有BUG的,或者说应用上有一些限制,好象是说由于只读属性导致的……
INITRD里有个脚本里也说,某项功能没启用,是因为它在UNIONFS环境下工作的不太好 ,具体没研究
不过我确实遇到过莫名其妙的问题,还是决定,长期用的话,不用UNIONFS
头像
ptptptptptpt
帖子: 3711
注册时间: 2006-09-19 18:16

#6

帖子 ptptptptptpt » 2006-09-21 9:51

原来已经加精了,感谢斑竹!

修正一下,发贴时忘了,12fstab文件改后还得加个函数

……
……
……
get_fstype() {
local FSTYPE
local FSSIZE
eval $(fstype < $1)
if [ "$FSTYPE" != "unknown" ]; then
echo $FSTYPE
return 0
fi
/lib/udev/vol_id -t $1 2>/dev/null
}



cat > $FSTAB <<EOF
# unionfs / unionfs rw 0 0
$rootdev / $(get_fstype "${rootdev}") rw 0 0
tmpfs /tmp tmpfs nosuid,nodev 0 0
EOF

rm -f /root/etc/rcS.d/S10checkroot.sh

log_end_msg
头像
gnix_oag
帖子: 1994
注册时间: 2005-05-19 18:38
来自: 湖南永州
联系:

Re: 高星兄我就是学的你方法 :)

#7

帖子 gnix_oag » 2006-09-22 7:04

ptptptptptpt 写了:一开始我也是照你介绍的那样做的,而且那样有个好处就是,可以随时把系统轻易地恢复到最初状态,很有吸引力!
后来看到有些文章说UNIONFS是有BUG的,或者说应用上有一些限制,好象是说由于只读属性导致的……
INITRD里有个脚本里也说,某项功能没启用,是因为它在UNIONFS环境下工作的不太好 ,具体没研究
不过我确实遇到过莫名其妙的问题,还是决定,长期用的话,不用UNIONFS
我现在就一直这样用,没有什么问题,我想以后也不会去安装 Linux,一遍两遍的安装,麻烦。

UNIONFS里的BUG什么啊,INITRD里的哪个脚本说的?
好象是说由于只读属性导致的
用了 unionfs 文件就可写了
头像
ptptptptptpt
帖子: 3711
注册时间: 2006-09-19 18:16

#8

帖子 ptptptptptpt » 2006-09-25 20:00

“……
原理很简单,但真正操作起来有很多问题。比如我把iso的镜像目录/iso和一个空的可写目录/writable合并成/newiso,这是如果做



# cp /a.srpm /newiso/SRPMS/b.srpm



会报错,原因是/iso下没有/SRPMS/b.srpm文件,即使有的话也是只读的;而/writable下没有/SRPMS目录。这样unionfs就有些无所适从了。理想情况是unionfs在/writable下建立好SRPMS目录,然后把文件拷贝到那里。这并不是unionfs设计的初衷,需要对unionfs打补丁。可unionfs是个内核模块,本身还不太稳定,如果再加上这许多复杂功能,恐怕不是好的选择。

……”

忘了是哪的了,google一下

选中 桌面上的 dbuntu 文件夹,按 del键,会报错,说 属于另一个文件系统

initrd 里 ,scripts/casper-bottom/25configure_init

# Disable readahead since it doesn't play well with squashfs + unionfs
# use chmod instead of mv to not trigger unionfs bugs.
chmod -x /root/sbin/readahead-list
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙

#9

帖子 eexpress » 2006-09-25 21:28

复杂。没实用性。
硬件全部要检测,usb速度也慢些。
● 鸣学
头像
major
帖子: 281
注册时间: 2006-09-01 17:48

#10

帖子 major » 2006-09-30 20:02

eexpress 写了:复杂。没实用性。
硬件全部要检测,usb速度也慢些。
个人所需 ,应该支持,虽然复杂,毕竟也是一种使用方法。
头像
我思故我在
帖子: 101
注册时间: 2006-08-17 1:13

#11

帖子 我思故我在 » 2006-09-30 21:55

  这个方法太复杂,wiki里usb安装方案好使的多。
spzgy
帖子: 22
注册时间: 2006-10-02 0:19

#12

帖子 spzgy » 2006-10-02 19:06

这个非常实用.
kason
帖子: 24
注册时间: 2006-10-01 16:35

#13

帖子 kason » 2006-10-10 13:40

好贴!顶!!!!
头像
ptptptptptpt
帖子: 3711
注册时间: 2006-09-19 18:16

#14

帖子 ptptptptptpt » 2006-11-05 22:11

头像
lvjinhua
帖子: 436
注册时间: 2006-02-23 14:46
来自: 上海
联系:

#15

帖子 lvjinhua » 2006-11-07 21:38

好,真正的Linux Fans 就应该像 ptptptptptpt 这样研究新东西。
====
dubuntu-6.06-livecd-i386正式版正式完工!
====
*支持LiveCD硬盘启动
*Linux 2.6.15-23-686
*永中Office 2007
*LumaQQ+OpenQ+cycloneQQ
**N 多的编程及调试工具**
回复