深度探索linux操作系統系統構建和原理解析第四章

4.4構建一個基本的initramfs

創建一個initramfs文件夾

vita@lx-VirtualBox:/vita$ mkdir initramfs


vita@lx-VirtualBox:/vita/initramfs$ vim init


!/bin/bash
echo "Hello Linux!"
exec /bin/bash


vita@lx-VirtualBox:/vita/initramfs$ chmod a+x init


vita@lx-VirtualBox:/vita/initramfs$ mkdir bin
vita@lx-VirtualBox:/vita/initramfs$ cp ../sysroot/bin/bash bin/

檢查bash的動態庫

vita@lx-VirtualBox:/vita/initramfs$ ldd bin/bash
        0x00000001 => (not found)
        0x00000001 => (not found)
        0x00000001 => (not found)
由於之前問題沒有解決所以只能這樣了

initramfs中安裝這三個庫

vita@lx-VirtualBox:/vita/initramfs$ cp -d /vita/sysroot/lib/libdl* lib/
vita@lx-VirtualBox:/vita/initramfs$ cp \
> /vita/sysroot/lib/libc-2.15.so lib/
vita@lx-VirtualBox:/vita/initramfs$ cp -d \
> /vita/sysroot/lib/libc.so.6 lib/
vita@lx-VirtualBox:/vita/initramfs$ cp \
> /vita/cross-tool/i686-none-linux-gnu/lib/libgcc_s.so.1 lib/
vita@lx-VirtualBox:/vita/initramfs$ cp -d /vita/sysroot/lib/ld-* lib/

中間ldd檢查還是沒有解決問題忽略繼續

vita@lx-VirtualBox:/vita/initramfs$ find .
.
./bin
./bin/bash
./lib
./lib/ld-linux.so.2
./lib/libdl.so.2
./lib/libc-2.15.so
./lib/libc.so.6
./lib/libdl-2.15.so
./lib/libgcc_s.so.1
./lib/ld-2.15.so
./init



vita@lx-VirtualBox:/vita/initramfs$  find . | cpio  -o -H newc | gzip  -9 > /vita/initrd.img

將之放入boot中

vita@lx-VirtualBox:/vita/initramfs$ sudo mv ../initrd.img ../boot/

之後修改grub.cfg爲下面


menuentry 'vita' {
        set root='(hd0,2)'
        linux  /boot/bzImage root=/dev/sda2 ro
        initrd /boot/initrd.img
}



vita@lx-VirtualBox:/vita/build$ tar xvf ../source/coreutils-8.20.tar.xz

vita@lx-VirtualBox:/vita/build/coreutils-8.20$ ./configure --prefix=/usr

vita@lx-VirtualBox:/vita/build/coreutils-8.20$ echo $?
0

vita@lx-VirtualBox:/vita/build/coreutils-8.20$ make install


vita@lx-VirtualBox:/vita/build/coreutils-8.20$ echo $?
0



檢查依賴
vita@lx-VirtualBox:/vita$ ldd sysroot/usr/bin/ls
        0x00000001 => (not found)
        0x00000001 => (not found)
        0x00000001 => (not found)
之前ldd問題一直沒有解決

vita@lx-VirtualBox:/vita$ ldd sysroot/lib/librt.so.1
        0x00000001 => (not found)
        0x00000001 => (not found)
        0x00000001 => (not found)

vita@lx-VirtualBox:/vita$ ldd sysroot/lib/libpthread.so.0
        0x00000001 => (not found)
        0x00000001 => (not found)

將這些動態鏈接庫複製到initramfs中去

vita@lx-VirtualBox:/vita$ cp sysroot/usr/bin/ls initramfs/bin/
vita@lx-VirtualBox:/vita$ cp -d sysroot/lib/librt* initramfs/lib/

vita@lx-VirtualBox:/vita$ cp -d sysroot/lib/libpthread*  initramfs/lib/

編譯工具mount

vita@lx-VirtualBox:/vita/build$ tar xvf ../source/util-linux-2.22.tar.xz


vita@lx-VirtualBox:/vita/build/util-linux-2.22$ ./configure \
> --prefix=/usr --disable-use-tty-group --disable-login \
> --disable-sulogin --disable-su --without-ncurses



vita@lx-VirtualBox:/vita/build/util-linux-2.22$ echo $?
0
配置成功編譯

vita@lx-VirtualBox:/vita/build/util-linux-2.22$ make && make install

接下來用ldd檢測mount依賴,這裏忽略

vita@lx-VirtualBox:/vita$ cp -d sysroot/lib/libmount.so.1* \
>  initramfs/lib/
vita@lx-VirtualBox:/vita$ cp -d sysroot/lib/libblkid.so.1*  initramfs/lib/
vita@lx-VirtualBox:/vita$ cp -d sysroot/lib/libuuid.so.1*  initramfs/lib/

 接下來就是配置內核,忽略



內核編譯好後添加了devtmpfs將至複製過去


lxiang@lxiang-Aspire-5750G:~/workplace_IDE/deepin_linux_workplace/linux-3.7.4$ scp arch/x86/boot/bzImage  [email protected]:/vita/boot
[email protected]'s password:
bzImage                                       100% 1595KB   1.6MB/s   00:00   


重新將磁盤驅動編譯爲模塊

lxiang@lxiang-Aspire-5750G:~/workplace_IDE/deepin_linux_workplace/linux-3.7.4$ make bzImage && make modules

make \
> INSTALL_MOD_PATH=$SYSROOT modules_install


vita@lx-VirtualBox:/vita$ mkdir -p \
> initramfs/lib/modules/3.7.4/kernel/drivers/ata
vita@lx-VirtualBox:/vita$ cp \
> sysroot/lib/modules/3.7.4/kernel/drivers/ata/* initramfs/lib/modules/3.7.4/kernel/drivers/ata


安裝kmod

vita@lx-VirtualBox:/vita/build/kmod-12$ tar xvf ../source/kmod-12.tar.xz


vita@lx-VirtualBox:/vita/build/kmod-12$ cd kmod-12/

vita@lx-VirtualBox:/vita/build/kmod-12$ ./configure --prefix=/usr

vita@lx-VirtualBox:/vita/build/kmod-12$ make && make install

vita@lx-VirtualBox:/vita/build/kmod-12$ find $SYSROOT \
> -name "*.la" -exec rm -f '{}' \;、

檢測kmod依賴並複製動態鏈接庫

vita@lx-VirtualBox:/vita$ cp sysroot/usr/bin/kmod initramfs/usr/bin/

複製動態鏈接庫
vita@lx-VirtualBox:/vita$ cp -d sysroot/usr/lib/libkmod.so.2* initramfs/lib/


爲kmod創建符號鏈接

vita@lx-VirtualBox:/vita/sysroot/sbin$ ln -s ../usr/bin/kmod  insmod
vita@lx-VirtualBox:/vita/sysroot/sbin$ ln -s ../usr/bin/kmod  rmmod
vita@lx-VirtualBox:/vita/sysroot/sbin$ ln -s ../usr/bin/kmod  modinfo
vita@lx-VirtualBox:/vita/sysroot/sbin$ ln -s ../usr/bin/kmod  lsmod  
vita@lx-VirtualBox:/vita/sysroot/sbin$ ln -s ../usr/bin/kmod  modprobe
vita@lx-VirtualBox:/vita/sysroot/sbin$ ln -s ../usr/bin/kmod  depmod 

拷貝到iinitramfs

vita@lx-VirtualBox:/vita/sysroot/sbin$ cd ../../
vita@lx-VirtualBox:/vita$ mkdir initramfs/sbin
vita@lx-VirtualBox:/vita$ cd sysroot/sbin/
vita@lx-VirtualBox:/vita/sysroot/sbin$ cp -d insmod rmmod modinfo lsmod modprobe depmod /vita/initramfs/sbin/

重新壓縮initrd.img

vita@lx-VirtualBox:/vita$ cd initramfs/
vita@lx-VirtualBox:/vita/initramfs$ find . | cpio  -o -H newc | gzip  -9 > /vita/initrd.img
34056 blocks


#!/bin/bash
echo "Hello Linux!"
export PATH=/usr/sbin:/usr/bin:/sbin:/bin
#mount  devtmpfs
mount -n -t devtmpfs udev /dev
mount -n -t proc proc /proc
mount -n -t sysfs sysfs /sys
exec /bin/bash


哭之後的編輯後忘了保存,大夥兒自己敲吧!!

switch_root.c
#include<errno.h>
#include<dirent.h>
#include<sys/stat.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/mount.h>
#include<fcntl.h>
#include<unistd.h>

int delet_dir(char *directory);

void delete(char *what)
{
	if(unlink(what)){
		if (errno ==EISDIR){
			if (!delete_dir(what))rmdir(what);		
		}
	}
}

int delete_dir(char *directory)
{
	DIR *dir;
        struct dirent *d;
	struct stat st1,st2;
	char path[PATH_MAX];
	if(lstat(directory,&st1))return errno;
	if(!(dir = opendir(directory)))return errno;
	while((d = readdir(dir))){
	    if(d->d_name[0] == '.' && (d->d_name[1] == '\0' || (d->d_name[1] == '.' && d->d_name[2] == '\0') ))continue;
	sprintf(path,"%s/%s",directory,d->d_name);
	if(st2.st_dev != st1.st_dev)continue;
	
	delete(path);
	}
	closedir(dir);
return 0;
}

int main(int argc,char*argv[])
{
	int console_fd;
	chdir(argv[1]);
	delete_dir("/");
	mount(".","/",NULL,MS_MOVE,NULL);
	chroot(".");
	chdir("/");
	
console_fd = open("/dev/console",O_RDWR);
dup2(console_fd,0);
dup2(console_fd,1);
dup2(console_fd,2);
close(console_fd);
execlp(argv[2],argv[2],NULL);
return 0;

}


#!/bin/bash
echo "Hello Linux!"
export PATH=/usr/sbin:/usr/bin:/sbin:/bin
export ROOTMNT=/root
export ROFLAG=-r
mount -n -t devtmpfs udev /dev
mount -n -t proc proc /proc
mount -n -t sysfs sysfs /sys
mount -n -t ramfs ramfs /run
udevd --daemon
udevadm trigger --action=add
udevadm settle

for x in $(cat /proc/cmdline); do
    case $x in
    root=*)
        ROOT=${x#root=}
        ;;
    ro)
        ROFLAG=-r
        ;;
    rw)
        ROFLAG=-w
        ;;
    esac
done

mount ${ROFLAG} ${ROOT} ${ROOTMNT}

# Stop udevd
udevadm control --exit
# Move to the real filesystem
mount -n --move /dev ${ROOTMNT}/dev
mount -n --move /run ${ROOTMNT}/run
mount -n --move /proc ${ROOTMNT}/proc
mount -n --move /sys ${ROOTMNT}/sys

switch_root ${ROOTMNT} /sbin/init



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章