天天看點

利用hashicorp packer把dbcolinux導出為虛拟機和docker格式(3)

本文關鍵字:gcc enable shared cross compile,multiarch gcc,multilib gcc,cross compile gcc under tinycorelinux

在 《利用hashicorp packer把dbcolinux導出為虛拟機和docker格式》1,2中,我們實作了基本的hd pe環境和釋放到hd /能啟動的硬碟環境,且編譯出了for 64的gcc cross toolchain和64 kernel,那麼現在,我們需要使之釋放到hd /system下還能啟動,且未來将繼續這個/system下的32/64混合rootfs的一些強化工作,将之打造成一個高可用的系統.

我們先來完成最基本的效果,即實作《在tinycolinux上組建子目錄引導和混合32位64位的rootfs系統》一文提到的效果:初步組建這個/system rootfs,并驗證/system下的rootfs能不能夠啟動。——— 本文完成的我們稱它為3264rootfsbase,未來繼續強化至3264systemfull.

我們的計劃是,按上面的安排,分二步,形成phase1->phase2的效果,phase1即dbcolinuxbase,=前面的toolchain+kernel+基本rootfs的打造。phase2即build3264systemfull,在以後的文章中《打造子目錄引導和混合32位64位的rootfs系統全部》再講述和豐富。第一步的dbcolinuxbase做成一個pvm,即parallels的"type": "parallels-iso”模式,第二步的後續dbcolinuxfull要從這個iso生成的pvm生成,即parallels的"type": "parallels-pvm" builder模式,對應2個phases,這樣便于內建,和調試。嘗試packer的新東西。且phase2可以直接複用phase1的結果持續內建.

1,packer檔案,其它準備工作

由于換了osx加parallelsdesk,我們需要改變一下基本的packer檔案,以下隻提到加的部分,文章1,2中有的部分會省略:

builders中是這樣:

"type": "parallels-iso",
"guest_os_type": "linux",
"hard_drive_interface": "ide",
……
"parallels_tools_flavor": "lin",
……
"boot_wait": “4s",
"shutdown_command": "sudo poweroff",
……
"prlctl": [["set", "{{.Name}}", "--startup-view", "window"]],

"boot_command":
[
……
"tce-load -iw parted.tcz<return>",
"tce-load -iw grub2.tcz<return>",
"tce-load -iw squashfs-tools-4.x.tcz<return>",
……

整合了這裡為compiletc,base-dev包含linux header
"echo 'setup gcccore pkgs...'<return>",
"tce-load -iw compiletc.tcz<return>",

"echo 'setup gccextra pkgs...'<return>",
"tce-load -iw perl5.tcz<return>",
"tce-load -iw ncurses.tcz<return>",
"tce-load -iw ncurses-dev.tcz<return>"
……
]           

可見,為了調試,1,2步友善持續內建,我們還把整個gcc放進了bootcommand,還整合進了一些必要庫和工具。

再準備檔案,與packer檔案同層的src檔案夾中,分成了/base和/others中,這樣的檔案夾安排,base對應phase1,是原來的編譯toolchain,64kernel所用的源碼檔案夾+.x tinycorelinux 中的 src repos/busybox-1.19.0patched.tar.gz,busybox-1.19.0-config。,而others對應phase2所要用到的源碼包。有autoscan-devices.copenssl-1.0.1.tar.gz,openssh-5.8p1.tar.xz,sudo-1.7.2p6.tar.gz,libzip-0.10.tar.xz,make-3.81.tar.gz,etc..

是以,"provisioners”部分會是這樣:

{"type": "shell","pause_before":"1s","execute_command": "echo '' | sudo -S sh -c '{{ .Vars }} {{ .Path }}'","inline":["cp -R /tmp/tce ~/"]},
{"type": "shell","pause_before":"1s","execute_command": "echo '' | sudo -S sh -c '{{ .Vars }} {{ .Path }}'","scripts":["./scripts/1.bootstrap.sh"]},

由于我們稍後的bootstrap中會不再釋放microcore.cpio,這個tmp要事先生成。
……
"sudo sh -c 'mkdir /mnt/hda1/tmp/'",
"sudo sh -c 'chown tc:staff /mnt/hda1/tmp/'"
……
{"type": "file","source": "src/base","destination": "/mnt/hda1/tmp"},

{"type": "shell",
"pause_before":"1s",
"execute_command": "echo '' | sudo -S sh -c '{{ .Vars }} {{ .Path }}'",
"scripts":
[
"./scripts/2.1.build64toolchainandkernel.sh",
"./scripts/2.2.build3264rootfsbase.sh"
]
}           

可見原來的2,3整合了成了2,這裡的script3是要新加的,為了友善調試,在packer的輸出視窗中簡便檢視起見,包括上面的packer盡量将簡單的樹形xml寫在行内,接下來的腳本中,我們也作了一些小的改變和與原來文章中的不同調整:

我們把重要的注釋換成了echo “ing …”,腳本中,解壓檔案的都不加verbose,涉及到編譯toolchain,kernel的地方。都./configure CC=“gcc -w”,且以上統一都 > /dev/null,還有,toolchain單獨一個檔案夾,與基礎rootfs所需的/lib,/lib64分開,我們還将切換native gcc/剛建的cross gcc的方法不再使用export CROSS_COMPILE,而直接用檔案名。

調試語句上,發現前面文章寫的,一句letitdebug的無義語句,放在位置放在腳本尾或強行斷點處并不能讓on error ask斷下來,reboot會産生斷點讓後面的語句無法運作,但也會丢失目前環境,packer -debug還是最可用的,除了它每執行一步都問一句有點煩之外,packer不支援-debug-on-error。

這些大部分都需要在腳本層更改,我們一件一件來:

2,bootstrap腳本的變動

因為我們要形成純淨的/system,是以去掉了/下的系統(以下注釋掉了部分),整個bootstrap會是這樣:

echo "HD INSTALL..."
#以下适合/的情況
#cd /mnt/hda1/
#gunzip -c /mnt/hda1/boot/microcore.gz > /tmp/microcore.cpio
#cpio -idmv < /tmp/microcore.cpio

#tce-load不能sudo,隻能unsquashfs方式安裝
#cp -R /tmp/tcloop/squashfs-tools-4.x/usr/ /mnt/hda1/
#unsquashfs -f -d /mnt/hda1/ /mnt/hda1/tce/optional/gcc_libs.tcz
#unsquashfs -f -d /mnt/hda1/ /mnt/hda1/tce/optional/openssl-0.9.8.tcz
#unsquashfs -f -d /mnt/hda1/ /mnt/hda1/tce/optional/openssh.tcz
#ldconfig
#tar zxf /mnt/hda1/mydata.tgz -C /mnt/hda1/

#/下,tce=hda1實測運作tce-load是無效的
#echo menuentry \"dbcolinux hd\" { >> /mnt/hda1/boot/grub/grub.cfg
#echo  linux /boot/bzImage com1=9600,8n1 loglevel=3 user=tc console=ttyS0 console=tty0 noembed nomodeset root=/dev/hda1 swapfile=hda1 tce=hda1 opt=hda1 home=hda1 norestore >> /mnt/hda1/boot/grub/grub.cfg
#echo } >> /mnt/hda1/boot/grub/grub.cfg

#以下适合/system的情況
mkdir /mnt/hda1/system/

#除了grub條目,所有其它東西要一點點靠組裝,或編譯出來,注意這裡加了root,init,以及norestore,copyfiles tce是為了restore,這裡用不着
echo menuentry \"dbcolinux systemhd\" { >> /mnt/hda1/boot/grub/grub.cfg
echo  linux /boot/bzImage64 com1=9600,8n1 loglevel=3 user=tc console=ttyS0 console=tty0 noembed nomodeset root=/dev/hda1 init=/system/linuxrc swapfile=hda1 tce=hda1 opt=hda1 home=hda1 norestore >> /mnt/hda1/boot/grub/grub.cfg
echo } >> /mnt/hda1/boot/grub/grub.cfg           

3,patch源碼部分

這些檔案是經過修改的,在接下來的scripts會被釋放覆寫相應的源碼檔案夾中的對應層次,形成patch的效果。是以它的結構保留了原源碼檔案夾的結構。然後打包成xx patch.tgz檔案,有:linux-2.6.33.3_patchs,glibc-2.11.1_patchs,busybox-1.19.0_patchs,patched的部分請去文章3中去對照。也可以直接去源碼庫中找。

4, /scripts/2.build64toolchainandkernel.sh

這裡主要是文章2,原來腳本2,3的強化和修正:

……
echo "compiling binutils ......"
#這裡設成shared,因為lib64中的ld要突出so,ld-*稍後需要複制一份出來
#shared模式下編譯64bit bfd會出現ar:file truncated問題,是以要編譯二次,fix一次tce-load compiletc裡那個,它會安裝到/usr/local/bin/
cd ../binutils-2.20 && mkdir b && cd b
../configure CC="gcc -w" -enable-64-bit-bfd > /dev/null
make > /dev/null
make install > /dev/null
cd ../../binutils-2.20 && mkdir b2 && cd b2
#隻要binutils -enable-shared,那麼用它編譯的gcc必定也是-enable-shared,,會影響接下來c libs.cpplibs全是shared
../configure CC="gcc -w" -prefix=/mnt/hda1/system/toolchain -target=$TARGET -enable-shared -disable-multilib -enable-64-bit-bfd > /dev/null
make > /dev/null
make install > /dev/null
……

echo "compiling c lib startups ......"
#标準C庫頭檔案和一些必要啟動檔案
#畢竟,通過export cross compile切換cross compile是不好的,我們幹脆手動指定,一了百了
#如果cross compile gcc出錯,出現fenv.h找不到那就是你改動了一些prefix檔案夾,如果出現tls.h找不到,那麼就是x86_64-pc-linux-gnu-gcc與gcc你沒用對,compiling c libs,二處都是x86_64-pc-linux-gnu-gcc而不是gcc
tar zxf /mnt/hda1/tmp/base/glibc-2.11.1_patchs/Archive.tgz -C /mnt/hda1/tmp/base/glibc-2.11.1/
cd ../../glibc-2.11.1 && mkdir b && cd b
#在glibc眼裡,這裡的build和host一個意思,與标準的其它三元組意義不同
../configure CC="x86_64-pc-linux-gnu-gcc -w" -prefix=/mnt/hda1/system/toolchain/$TARGET -build=$MACHTYPE -host=$HOST -target=$TARGET -with-headers=/mnt/hda1/system/toolchain/$TARGET/include -disable-multilib libc_cv_forced_unwind=yes libc_cv_c_cleanup=yes > /dev/null
make install-bootstrap-headers=yes install-headers > /dev/null
make csu/subdir_lib > /dev/null
install csu/crt1.o csu/crti.o csu/crtn.o /mnt/hda1/system/toolchain/$TARGET/lib > /dev/null
#利用新編的64gcc處理
x86_64-pc-linux-gnu-gcc -nostdlib -nostartfiles -shared -x c /dev/null -o /mnt/hda1/system/toolchain/$TARGET/lib/libc.so > /dev/null
……

echo "compiling c++ libs ......"
#标準C++庫
#這是一個bug1
ln -s /usr/local/bin/file /usr/bin/file
cd ../../gcc-4.4.3/b/
……
make CC="x86_64-pc-linux-gnu-gcc -w" bzImage > /dev/null
make CC="x86_64-pc-linux-gnu-gcc -w" modules > /dev/null
make modules_install INSTALL_MOD_PATH=/mnt/hda1/system > /dev/null
ln -s /system/lib/modules/2.6.33.3-tinycore64/kernel /mnt/hda1/system/lib/modules/2.6.33.3-tinycore64/kernel.tclocal

cp -f arch/x86/boot/bzImage /mnt/hda1/boot/bzImage64           

5,scripts/3.build3264rootfsbase.sh

這是新加的整個腳本3:

export PATH=$PATH:/usr/local/sbin:/usr/local/bin

cd /mnt/hda1/tmp/base/
tar zxf busybox-1.19.0patched.tar.gz

echo "making basic rootfs lib,lib64......"
#gcc test.c一個demo,/usr/bin/ldd測試它,就可以找出要運作它的dys
#注意這裡,複制32 ld-*,dylibs部分
#/mnt/hda1/system/lib/在前面腳本安裝lib/modules時被建立了
cp /lib/lib*.so* /mnt/hda1/system/lib/
cp /lib/ld-2.11.1.so /mnt/hda1/system/lib/ld-2.11.1.so
chmod +x /mnt/hda1/system/lib/ld-2.11.1.so
#再來套/lib64下的
mkdir /mnt/hda1/system/lib64/
cp /mnt/hda1/system/toolchain/x86_64-pc-linux-gnu/lib/lib*.so* /mnt/hda1/system/lib64/
cp /mnt/hda1/system/toolchain/x86_64-pc-linux-gnu/lib/ld-2.11.1.so /mnt/hda1/system/lib64/ld-2.11.1.so
chmod +x /mnt/hda1/system/lib64/ld-2.11.1.so
cp /mnt/hda1/system/toolchain/x86_64-pc-linux-gnu/lib64/lib*.so* /mnt/hda1/system/lib64/
#連結,file ./ld-linux.so.2可查出來
ln -s /system/lib/ld-2.11.1.so /mnt/hda1/system/lib/ld-linux.so.2
ln -s /system/lib64/ld-2.11.1.so /mnt/hda1/system/lib64/ld-linux-x86-64.so.2

echo "compiling busybox ......"
tar zxf /mnt/hda1/tmp/base/busybox-1.19.0_patchs/Archive.tgz -C /mnt/hda1/tmp/base/busybox-1.19.0/
cd busybox-1.19.0
make mrproper > /dev/null
cp -f ../busybox-1.19.0-config configs/i686_defconfig
make i686_defconfig > /dev/null
#還可以加CROSS_COMPILE=
#有些檔案編碼問題會導緻下面的-變成...,如果出現/usr/local/bin/ld rpath=/system/lib no such file no such file or directory,可能就是這類錯誤了,很詭異
make CC="gcc -Wl,–rpath=/system/lib -Wl,–dynamic-linker=/system/lib/ld-linux.so.2" CONFIG_PREFIX=/mnt/hda1/system/ install > /dev/null

echo "make basic rootfs data..."
mkdir /mnt/hda1/system/dev
cd /mnt/hda1/system/dev
mknod console c 5 1
mknod null c 1 3

mkdir /mnt/hda1/system/etc
cd /mnt/hda1/system/etc

touch fstab
echo proc /system/proc proc defaults 0 0 >> fstab
echo sysfs /system/sys sysfs defauts 0 0 >> fstab

touch inittab
chmod +x inittab
echo ::sysinit:/system/etc/init.d/rcS >> inittab
echo console::respawn:-/system/bin/sh >> inittab
echo ::ctrlaltdel:/system/sbin/reboot >> inittab
echo ::shutdown:/system/bin/umount -a -r >> inittab

mkdir /mnt/hda1/system/etc/init.d
cd /mnt/hda1/system/etc/init.d
touch rcS
chmod +x rcS
echo #!/system/bin/sh >> rcS
echo /system/bin/mount -a >> rcS

mkdir /mnt/hda1/system/proc
mkdir /mnt/hda1/system/sys

#clean
#rm -rf /mnt/hda1/tmp/base/
#reboot           

—————

最後,進入新生成的grub系統條目,出現指令行要先export PATH=$PATH:/system/bin:/system/sbin,應該是patchs沒做好。下回做。

(此處不設回複,掃碼到微信參與留言,或直接點選到原文)

利用hashicorp packer把dbcolinux導出為虛拟機和docker格式(3)