修改initrd实现BackTrack 4 Pre 从硬盘ISO文件启动

引导部分修改

引导部分和之前的BT4 BETA一样
C盘boot.ini中添加以下部分
[operating systems]

multi(0)disk(0)rdisk(0)partition(1)WINDOWS="Microsoft Windows XP Professional" /noexecute=optin /fastdetect

c
:grldr="BackTrack 4 Pre Release"

复制grub4dos-0.4.4-2009-06-20.zip中的grldr到C盘根目录下

新建c盘根目录下menu.lst,主要内容来自BT4自带的menu.lst,添加了参数casperroot用于标识查找的路径(e.g. casperroot=BT4 即在磁盘根目录的BT4文件夹下查找ISO等文件,其中的BOOT=suddy boot=suddy则是修改的启动脚本为(initrd.gz解开后)/scripts/suddy, /script/casper为原先默认脚本)

内容如下:

# By default, boot the first entry.

default 0


# Boot automatically after 30 secs.

timeout 30


splashimage
=(hd0,4)/BT4/boot/grub/bt4.xpm.gz


title         Start BackTrack FrameBuffer 
(1024x768)

kernel     (hd0,4)/BT4/boot/vmlinuz BOOT=suddy boot=suddy casperroot=BT4 nopersistent rw quiet vga=0x317

initrd     
(hd0,4)/BT4/boot/initrd.gz


title         Memory Test

kernel     
(hd0,4)/BT4/boot/memtest86+.bin


title         Boot the First Hard Disk

root         
(hd0)

chainloader +1


title         Start Windows

rootnoverify 
(hd0,0)

makeactive

chainloader 
+1                    


title         Shutdown the Computer

halt


title         Reboot the Computer

reboot

initrd.gz修改

解压initrd.gz

gunzip initrd.gz


mkdir src


cd src


cpio 
-iF ../initrd

修改启动脚本src/script/casper

我是直接复制一份原来的casper重命名为suddy,增加对kernel 参数casperroot的识别

如果分区的casperroot指向目录下有liveCD的ISO 则优先选择加载ISO,否则,则查找是否有casper目录,有的话查找filesystem.squashfs进行加载。

如果ISO同目录下有文件名为*.fs的文件(这里用的是Backtrack.fs(ext3)),则使用其作为系统修改的保存地址。

如果ISO同目录下有文件名为*.swap (这里用的是Backtrack.swap(swap)),则用它作为系统的swap分区。

这里面比较郁闷的就是ntfs分区的加载,开始的时候使用默认的mount -t ntfs 进行加载,无论如何都不能mount成可写的,原因没有找到,后来尝试ntfs-3g进行加载,才终于rw的mount上。悲剧啊。

e.g.

mount -t ntfs-3g -o rw,noatime "${devname}" $mountpoint || continue

还有一点就是chroot, liveCD的启动本质上是先在一个目录下配置好linux的运行文件,然后chroot过去,改造中由于这个就碰到了问题。

Backtrack.fs开始的时候是mount在/rwfs下的,liveCD的目录却是/root. 这样在脚本chroot到 /root目录下作为新系统的根目录的时候,mount节点的记录还是在原来的地址,也就是在新的根的上一层目录的rwfs下,这样,在新系统中就无法访问到/rwfs.

解决办法也很简单,使用mount -o move移动到chroot目标目录下级目录即可

e.g.

# move the stofs ; no head in busybox-initramfs

     
if [ "${storefs_fstype}" != "" ]; then

             mkdir 
-"${rootmnt}/rwfs"

          
mount -o move "/storefs" "${rootmnt}/rwfs"

     
fi

这样在使用 chroot 后就处于能访问的范围。就不影响使用了(路径的变化在使用chroot后系统会自动识别)

详细修改如下:

diff -uprBN casper suddy


    
--- casper         2009-07-20 03:23:27.563787200 +0800

+++ suddy         2009-07-20 00:11:31.164010800 +0800

@@ -30,+30,@@ fi

    parse_cmdline
() {

         for 
x in $(cat /proc/cmdline); do

             case 
$x in

+              casperroot=*)

+              
export CASPERROOT="${x#casperroot=}";;

                 
persistent)

                         export PERSISTENT="Yes" ;;

                 nopersistent)

@@ -52,7 +54,15 @@ parse_cmdline() {

    }

    

    is_casper_path() {

-     path=$1

+     if [ "
${CASPERROOT}" = "" ]; then

+             path=$1

+     else

+         path="
$1/${CASPERROOT}"

+     fi

+     
# modify the path to $1 if it's a iso file

+     if [ "$ISISO" != "" ]; then

+             path=$1

+     fi

         if [ -d "
$path/casper" ]; then

             if [ "
$(echo $path/casper/*.squashfs)" != "$path/casper/*.squashfs" ] ||

                 [ "
$(echo $path/casper/*.ext2)" != "$path/casper/*.ext2" ] ||

@@ -81,7 +91,8 @@ matches_uuid() {

    

    get_backing_device() {

         case "$1" in

-             *.squashfs|*.ext2)

+         
# add the ext of *.fs to doing with storefilesystem sth like Backtrack.fs

+             *.squashfs|*.ext2|*.fs)

                 echo $(setup_loop "$1" "loop" "/sys/block/loop*")

                 ;;

             *.dir)

@@ -104,7 +115,14 @@ match_files_in_dir() {

    }

    

    mount_images_in_directory() {

-     directory="$1"

+     if [ "
${CASPERROOT}" = "" ]; then

+             directory="$1"

+     else

+         directory="
$1/${CASPERROOT}"

+     fi

+     if [ "$1" = "/iso9660" ]; then

+             directory="$1"

+     fi

         rootmnt="$2"

         if match_files_in_dir "
$directory/casper/*.squashfs" ||

             match_files_in_dir "
$directory/casper/*.ext2" ||

@@ -395,7 +413,43 @@ setup_unionfs() {

    

         mount -t ${cow_fstype} -o ${cow_mountopt} ${cowdevice} /cow || panic "
Can not mount $cowdevice on /cow"

    

-     mount -t ${UNIONFS} -o noatime,dirs=/cow=rw:$rofsstring ${UNIONFS} "
$rootmnt" || panic "${UNIONFS} mount failed"

+     
# mkdir a filesystem to mount the *.fs

+     if [ "${CASPERROOT}" = "" ]; then

+             storefs="
$mountpoint"

+     else

+         storefs="
$mountpoint/${CASPERROOT}"

+     fi

+     
# if a *.fs in the patch of the boot directory, use unionfs to mount to /

+     if [ "$(echo $storefs/*.fs)" != "$storefs/*.fs" ] ; then

+         rwfs="
$(echo $storefs/*.fs)"

+         
#mkdir -p /storefs

+         #storefs_fstype=$(get_fstype $rwfs) 

+         #storefs_mountopt="rw,noatime"

+         #mount -t     $storefs_fstype -o $storefs_mountopt $rwfs /storefs

+

+         storefs_backdev=$(get_backing_device "
$rwfs")

+             storefs_fstype=$(get_fstype "
${storefs_backdev}")

+             if [ "
${storefs_fstype}" = "unknown" ]; then

+              panic "
Unknown file system type on ${storefs_backdev} ($rwfs)"

+         fi

+             mkdir -p "/storefs"

+             mount -t "
${storefs_fstype}" -o rw,noatime "${storefs_backdev}" "/storefs" || panic "Can not mount $storefs_backdev ($rwfs) on /storefs

+                 

+         
#mkdir -p "/root1"

+         # mount with storefs to store the change

+         mount -t ${UNIONFS} -o noatime,dirs=//storefs=rw:$rofsstring ${UNIONFS} "$rootmnt" || panic "${UNIONFS} mount failed"

+         #mount -t ${UNIONFS} -o noatime,dirs=//storefs=rw:/cow=rw:$rofsstring ${UNIONFS} "$rootmnt" || panic "${UNIONFS} mount failed"

+         #mount -t ${UNIONFS} -o noatime,dirs=//storefs=rw:/cow=rw:$rofsstring ${UNIONFS} "/root1" || panic "${UNIONFS} mount failed"

+     else

+         mount -t ${UNIONFS} -o noatime,dirs=/cow=rw:$rofsstring ${UNIONFS} "
$rootmnt" || panic "${UNIONFS} mount failed"

+     fi

+

+     
# if a *.swap in the patch of the boot directory, use it like a swap file

+     if [ "$(echo $storefs/*.swap)" != "$storefs/*.swap" ] ; then

+         swapfs="
$(echo $storefs/*.swap)"

+         swapon $swapfs

+         echo "
$swapfs swap     swap     defaults     0     0">> "$rootmnt"/etc/swap_fstab

+     fi

    

         
# Adding other custom mounts

         
if [ -n "${PERSISTENT}" ]; then

@@ -428,6 +482,17 @@ setup_unionfs() {

             mount -o bind /cow "
${rootmnt}/cow"

         fi

    

+     
# move the stofs ; no head in busybox-initramfs

+     if [ "${storefs_fstype}" != "" ]; then

+         mkdir -p "
${rootmnt}/rwfs"

+         mount -o move "/storefs" "
${rootmnt}/rwfs"

+     fi

+

+     for d in $(mount -t iso9660 | cut -d     -f 3); do

+         mkdir -p "
$rootmnt/iso9660"

+         mount -o move "
${d}" "$rootmnt/iso9660"

+     done

+

         
# move the first mount; no head in busybox-initramfs

         
for d in $(mount -t squashfs | cut -d     -f 3); do

             mkdir -p "
${rootmnt}/rofs"

@@ -436,6 +501,38 @@ setup_unionfs() {

         done

    }

    

+find_iso()

+{

+     local isoroot="/iso9660"

+     local tmproot=$1

+     if [ "
${CASPERROOT}" = "" ]; then

+             isos=`ls ${tmproot}/*.iso 2>/dev/null` || return 1

+     else

+         isos=`ls ${tmproot}/${CASPERROOT}/*.iso 2>/dev/null` || return 1

+     fi

+     modprobe loop

+     mkdir -p "
$isoroot"

+     for iso in ${isos}

+     do

+         mount -t iso9660 -o loop $iso $isoroot 2>/dev/null || continue

+         
#if casper_path "$isoroot"; then

+         #send a sign to the function that is a iso file

+         ISISO="YES";

+         if is_casper_path "
$isoroot" ; then

+                 
#echo "$isoroot"/casper/filesystem.squashfs

+                 #in_iso_squashfs="$isoroot"/casper/filesystem.squashfs

+          in_iso_squashfs="$isoroot"

+                 return 0             

+         else

+          ISISO=""

+                 umount "
$isoroot"

+         fi

+     done

+     unset isos

+     unset iso

+     return 1

+}

+

    check_dev ()

    {

         sysdev="
${1}"

@@ -462,7 +559,15 @@ check_dev ()

    

         fstype=$(get_fstype "
${devname}")

         if is_supported_fs ${fstype}; then

-             mount -t ${fstype} -o ro,noatime "
${devname}" $mountpoint || continue

+         if [ ${fstype}="ntfs" ]; then

+              mount -t ntfs-3g -o rw,noatime "
${devname}" $mountpoint || continue

+         else

+              mount -t ${fstype} -o rw,noatime "
${devname}" $mountpoint || continue

+         fi

+         if find_iso $mountpoint ; then

+              echo $in_iso_squashfs

+              return 0

+         fi

             if is_casper_path $mountpoint && 

                 ([ "
$skip_uuid_check" ] || matches_uuid $mountpoint); then

                 echo $mountpoint

src/scripts/casper-bottom/10adduser修改

作用:增加保存上次修改的root密码的功能

主要是判断mount完联合文件系统后$rootmount/etc/shadow是否存在,如果存在则取出其中已有的root密码hash作为新系统的root密码hash。否则则新建shadow,用一个空格作为密码(hash:U6aMy0wojraho)

diff -uprBN old/scripts/casper-bottom/10adduser src/scripts/casper-bottom/10adduser

--- old/scripts/casper-bottom/10adduser    2009-07-20 03:23:27.579581500 +0800

+++ s/scripts/casper-bottom/10adduser    2009-07-20 05:38:21.375000000 +0800

@@ -20,10 +20,18 @@ esac

    

    log_begin_msg 
"$DESCRIPTION"

    

+# if there have a shadow file use the old password, if not, use a blank to create the new password

+if [ "$(echo /root/etc/shad*w)" "/root/etc/shad*w" ] ; then

+    passwd_old="U6aMy0wojraho"

+else

+    
passwd_old="$(cat /root/etc/shadow | grep "^root" | cut -d: -f 2)"

+    #echo "pass1:suddy have /root/etc/shadow"

+    #echo "pass is : $passwd_old"

+fi

    
# U6aMy0wojraho is just a blank password

    
chroot /root debconf-communicate -fnoninteractive casper > /dev/null <<EOF

    set passwd
/root-password-crypted *

-
set passwd/user-password-crypted U6aMy0wojraho

+set passwd/user-password-crypted $passwd_old

    set passwd
/user-fullname $USERFULLNAME 

    set passwd
/username $USERNAME

    set passwd
/user-uid 999

src/scripts/casper-bottom/25configure_init 修改:

作用:去除liveCD默认的免密码登录。

毕竟,装机器上如果直接一开机就是root的shell的话感觉也太不好了。

主要是去除了init中使用login -f username进行免登录的设置,修改后需要自己输入用户名和密码。

diff -uprBN old/scripts/casper-bottom/25configure_init src/scripts/casper-bottom/25configure_init

--- old/scripts/casper-bottom/25configure_init     2009-07-20 03:23:27.611170100 +0800

+++ s/scripts/casper-bottom/25configure_init     2009-07-20 00:27:31.425515400 +0800

@@ -24,11 +24,15 @@ log_begin_msg "$DESCRIPTION"

    

    
if [ -"$USERNAME" ]; then

         
if [ -/root/etc/inittab ]; then

-          sed --"s|^\([^:]*:[^:]*:[^:]*\):.*getty.*\<\(tty[0-9]*\).*$|\1:/bin/login -f $USERNAME </dev/\2 >/dev/\2 2>\&1|" /root/etc/inittab

+          #sed -i -e "s|^\([^:]*:[^:]*:[^:]*\):.*getty.*\<\(tty[0-9]*\).*$|\1:/bin/login -f $USERNAME </dev/\2 >/dev/\2 2>\&1|" /root/etc/inittab

+          # remove the longin -f param to disable autologin

+          sed --"s|^\([^:]*:[^:]*:[^:]*\):.*getty.*\<\(tty[0-9]*\).*$|\1:/bin/login </dev/\2 >/dev/\2 2>\&1|" /root/etc/inittab

         fi

         
if [ "/root/etc/event.d/tty*" != "$(echo /root/etc/event.d/tty*)" ]; then

              
for f in /root/etc/event.d/tty*; do

-               
sed --"s|^exec.*|exec /bin/login -f $USERNAME </dev/$(basename $f) > /dev/$(basename $f) 2>\&1|" $f

+               #sed -i -e "s|^exec.*|exec /bin/login -f $USERNAME </dev/$(basename $f) > /dev/$(basename $f) 2>\&1|" $f

+               # remove the longin -f param to disable autologin

+               sed --"s|^exec.*|exec /bin/login </dev/$(basename $f) > /dev/$(basename $f) 2>\&1|" $f

              done

              
for x in $(cat /proc/cmdline); do

                   case 
$x in

其他的修改请直接参考附件补丁:initrd.diff.gz

用于存储的fs文件和swap文件获取

最简单的办法直接下载现成的。

http://gniarf.nerim.net/colinux/swap/

http://gniarf.nerim.net/colinux/fs/

简单的使用方法

下载grldr.rar,解压到C盘根目录,修改boot.ini加入一行:

c:grldr="BackTrack 4 Pre Release"

在D盘根路径下建立文件夹BT4

把从bt4-pre-final.iso解出来的boot文件夹放在BT4下。

下载并使用initrd.gz(20090830update 去除41apt_cdrom)覆盖boot目录下的同名文件(修改initrd.gz,默认root密码:toor 2009-08-04更新,原因为root用户默认不能用空密码登录。)

bt4-pre-final.iso放在BT4文件夹下,把fs_512Mb.bz2解压也放在BT4目录下,并重命名为Backtrack.fs,把swap_256Mb.bz2解压也放在BT4目录下,并重命名为Backtrack.swap

完成后BT4的目录结构如下:

D:>tree /f BT4

文件夹 PATH 列表

卷序列号为 AA14
-AF15

D
:BT4

│     Backtrack
.fs

│     Backtrack
.swap

│     bt4
-mod.iso



└─boot

重启,选择BackTrack 4 Pre Release,然后选择Start BackTrack FrameBuffer (1024x768) 进入BT4(用户root,默认密码为一个空格字符).

附录以及杂七杂八的记录

相关命令:

补丁安装

到相应目录下

zcat xxx
.diff.gz patch -p1



补丁制作

diff 
-uprBN orig new >xxx.diff

gzip xxx
.diff


联合文件系统安装:

mount 
-t aufs -o dirs=./one=rw:./two=roaufs ./merged


initrd
.gz的解压缩和打包:

    gunzip initrd800
.gz

    cpio 
-iF ../initrd 解压缩

    find 
. | cpio --H newc gzip -> ../initrd.gz 压缩打包


bt4启动后启动lan连接:

dhclient (使用dhcp获取IP)

/sbin/route add -net 0.0.0.0 gw 1.1.1.1 eth0(添加默认路由)


使用文件作为系统swap以及查看
:

swapon /cdrom/BT4/Backtrack.swap

swapon 
-s


修改grub引导启动的分辨率
:

调整kernel参数中的&rdquo;vga=0x317&ldquo;

更多可选的值参考:http://en.wikipedia.org/wiki/VESA_BIOS_Extensions#Linux_video_mode_numbers

参考:

http://www.linuxfans.org/bbs/thread-160578-1-1.html

http://hi.baidu.com/tuming1986/blog/item/71b3eca3a70fe0abcaefd06c.html

http://gniarf.nerim.net/colinux/

http://www.fcicq.net/wp/?p=307

http://www.bo128.cn/article/09-06/58.html

http://en.wikipedia.org/wiki/VESA_BIOS_Extensions#Linux_video_mode_numbers

http://forum.ubuntu.org.cn/viewtopic.php?f=86&t=17909

http://forum.ubuntu.org.cn/viewtopic.php?t=11906

http://forum.ubuntu.org.cn/viewtopic.php?t=26243

http://forum.ubuntu.org.cn/viewtopic.php?t=26167

http://forum.ubuntu.org.cn/viewtopic.php?t=19340

http://forum.ubuntu.org.cn/viewtopic.php?f=86&t=21688&sid=f5da65c941f86881b1626ee77402bd45

« 上一篇 | 下一篇 »

12条记录访客评论

你好,我想问你个问题,我下的BT4.iso
解压出来是boot和casper两个文件夹,然后用了Grub做引导,一开始我是在C盘根目录下建了BT4,然后把那2个文件仍进去了,menu.lst也修改好了.在前面添加了/BT4/boot  了.成功引导,系统开始加载让我等待,不一会尔就出现了(initramfs) 加载不起来了.放到D盘也是同样的情况,文件系统是NTFS的,后来我就把那2个文件夹直接拖到C盘根目录了.在menu.lst里去除了/BT4 这个目录,成功进入了系统,问你下这是由什么原因导致的?我是想放在BT4文件夹里再引导启动,因为在windows文件夹显得美观点,呵呵.
求助..............该怎么做才可以套个文件夹成功引导并加载,现在是套了个文件夹就加载不了.

Post by alexsuz on 2010, January 21, 2:58 PM 引用此文发表评论 #1

我的MAIL  alexsuc@163.com
希望能帮助我下

Post by alexsuz on 2010, January 21, 2:59 PM 引用此文发表评论 #2

Final Release已经发布了,是否考虑更新一下那个initrd.gz文件啊!谢谢!

Post by xyz on 2010, January 22, 1:39 PM 引用此文发表评论 #3

引用 alexsuz 说过的话:
你好,我想问你个问题,我下的BT4.iso
解压出来是boot和casper两个文件夹,然后用了Grub做引导,一开始我是在C盘根目录下建了BT4,然后把那2个文件仍进去了,menu.lst也修改好了.在前面添加了/BT4/boot  了.成功引导,系统开始加载让我等待,不一会尔就出现了(initramfs) 加载不起来了.放到D盘也是同样的情况,文件系统是NTFS的,后来我就把那2个文件夹直接拖到C盘根目录了.在menu.lst里去除了/BT4 这个目录,成功进入了系统,问你下这是由什么原因导致的?我是想放在BT4文件夹里再引导启动,因为在windows文件夹显得美观点,呵呵.
求助..............该怎么做才可以套个文件夹成功引导并加载,现在是套了个文件夹就加载不了.


因为默认脚本查找是以根目录为基础路径查找的。这块的修改可以参考我文章中casperroot参数的部分,实现的就是你的那个需求

Post by ╰☆往事如风 on 2010, January 22, 8:29 PM 引用此文发表评论 #4

引用 xyz 说过的话:
Final Release已经发布了,是否考虑更新一下那个initrd.gz文件啊!谢谢!


To xyz
我现在用的还是这份的initrd.gz 引导release的iso是正常的。

Post by ╰☆往事如风 on 2010, January 22, 8:30 PM 引用此文发表评论 #5

[quote=╰☆往事如风][/quote]的确是照了你的方法改好的,能是能引导的,但就是加载不了系统.放到根目录下就行了
我就改了个menu.lst,想套个文件夹在外面是否initrd.gz也得改?

Post by alexsuz on 2010, January 24, 11:08 AM 引用此文发表评论 #6

引用 alexsuz 说过的话:
的确是照了你的方法改好的,能是能引导的,但就是加载不了系统.放到根目录下就行了我就改了个menu.lst,想套个文件夹在外面是否initrd.gz也得改?

是的。initrd.gz中启动脚本要做相应的修改。默认脚本只在根目录下查找

Post by ╰☆往事如风 on 2010, January 24, 10:11 PM 引用此文发表评论 #7

[quote=╰☆往事如风][/quote]
谢谢!原来是修改完后,忘记删除41apt_cdrom这个脚本,导致不能引导。删除后就可以正常引导bt4-final.iso了。

Post by xyz on 2010, January 27, 9:04 PM 引用此文发表评论 #8

谢谢,学习学习.

Post by 21q on 2010, November 24, 10:05 AM 引用此文发表评论 #9

能做个for BT4 rc2的么  谢谢

Post by tonway on 2011, March 10, 9:54 AM 引用此文发表评论 #10

按照以上办法。成功引导。加载是出现could not load .....modues.dep!
请问是什么问题呢?

Post by foua on 2011, April 18, 8:54 PM 引用此文发表评论 #11

引用 foua 说过的话:
按照以上办法。成功引导。加载是出现could not load .....modues.dep!
请问是什么问题呢?

是否是路径问题?没有完整信息不好判断

Post by ╰☆往事如风 on 2011, April 20, 12:15 AM 引用此文发表评论 #12


发表评论

评论内容 (必填):