2019年4月16日 星期二

制作initial RAM filesystem,以及讓kernel boot into RAM disk filesystem

首先會從u-boot的 bootargs參數開始,關鍵在於這兩個藍色字的參數,可以讓kernel booting到RAM disk

bootargs "root=/dev/ram0 rw console=ttyMV0,115200 earlycon=ar3700_uart,0xd0012000 no_console_suspend init=/init rootdelay=3 rootfstype=ext4"


當u-boot開到kernel之後,Kernel就會去把你包的Initial RAM filesystem 掛載到 root參數(也就是/dev/ram0) ,前提是你的 Initial RAM filesystem要記得要建立/dev/ram0

再來當你的 Initial RAM filesystem 掛載好之後,會接著去跑第二個參數 init這個檔案,init通常是一支shell script,也是kernel轉換到filesystem後的第一個檔案,他的動作通常會去掛載一些資料夾之後就幫忙導到linuxrc(也就是busybox),接著就成功進入作業系統


先列出我Build Code環境,各個資料夾的樹狀結構


















下面列出各個階段Programer需要作的事情:

1. U-Boot
修改 bootargs 參數,修改的內容如上面所敘述

2. 編譯Busybox
下載一包Busybox,先去執行make menuconfig,接著去設定要安裝的路徑,如下圖:
 Settings  --->
     --- Installation Options ("make install" behavior)


















接著,可以把Busybox編譯成Static Library的方式,如下圖:
Settings  --->
    [*] Build static binary (no shared libs)

















上面步驟都設定完成後,離開並儲存,在去作make install,最後會生出一個簡易的root filesystem(還不完整)


3. 制作 Initial RAM filesystem
請先到上個步驟當中,安裝Busybox的路徑,會看到如下圖,皆為Busybox所產生:






接著我們要繼續補足 Initial RAM filesystem所缺少的,分別作以下幾個步驟:
3-1. 建立 proc資料夾,sys資料夾 (mkdir proc; mkdir sys)
3-2. 建立 init檔案,其內容如下:
#!/bin/sh -x
MOUNT="/bin/mount"
${MOUNT} -t proc /proc /proc
${MOUNT} -t sysfs /sys /sys
${MOUNT} -t usbfs none /proc/bus/usb
${MOUNT} -t devpts devpts /dev/pts
/linuxrc

3-3. 建立dev資料夾,以及所需要的device node,執行 makedev.sh來建立,內容如下:
(內容較多,我把他補充再文章最後) ...

以上三個小步驟完成後,就建立出基本的 Initial RAM filesystem,如下圖:




4. Kernel
首先要先作make menuconfig,並且把 Initial RAM filesystem選像打開,並且選擇已經編譯好的busybox(我編譯好的busybox在kernel資料夾的上一層資料夾 ../build/fs.initrd/),路徑如下:
General setup ---->
     [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
     (../build/fs.initrd/) Initramfs source file(s)

存檔離開後,執行make,便會把Initial RAM filesystem包進Kernel當中



當上面的Kernel都準備好了之後,讓U-Boot booting進入Kernel. 應該就可以順利進入RAM filesystem了。


如果遇到Failed to execute /init (error -2)的Kernel Panic情形,請確認下面幾件事情
1. Busybox選項是否有開啟mount指令
2. Busybox是否有開啟Static Build
3. 請在安裝完Busybox之後,把產生出的busybox執行檔,權限改為Superuser (chmod +s busybox)


















用法: ./makedev.sh (busybox安裝路徑)

##################  makedev.sh ############################
#!/bin/sh

if [ x$1 == "x" ]; then
        echo ""
        echo "Usage:   makedev ROOTDIR"
        echo ""
        echo "  ROOTDIR is the directory of root FS, please use full path."
        echo ""
        exit 0
fi

rm -rf $1/dev/*
cd $1/dev/

DEVINDEX=(a b c d e f g h i j k l m n o p q r s t u v w x y z)
NODEINDEX=(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)
M_NUM=8
N_NUM=0
DEVNODE=sd
TYPE=b

major=${M_NUM}
minor=${N_NUM}

for i in ${DEVINDEX[@]} ; do
        mknod -m 660 ${DEVNODE}${i} ${TYPE} ${major} ${minor}
        let minor=minor+1

        for j in ${NODEINDEX[@]}; do
                mknod -m 660 ${DEVNODE}${i}${j} ${TYPE} ${major} ${minor}
                let minor=minor+1
        done

        if [ $minor -gt 255 ]; then
                let major=65
                let minor=0
        fi
done


mknod -m 600 mem        c 1 1
mknod -m 666 null       c 1 3
mknod -m 666 zero       c 1 5
mknod -m 644 random     c 1 8
mknod -m 444 urandom    c 1 9
mknod -m 600 tty0       c 4 0
mknod -m 600 tty1       c 4 1
mknod -m 600 tty2       c 4 2
mknod -m 600 tty3       c 4 3
mknod -m 600 tty4       c 4 4
mknod -m 600 tty5       c 4 5
mknod -m 600 ttys0      c 3 48
mknod -m 600 ttyS0      c 4 64
mknod -m 600 ttys1      c 3 49
mknod -m 600 ttyS1      c 4 65
mknod -m 600 ttys2      c 3 50
mknod -m 600 ttyS2      c 4 66
mknod -m 666 tty        c 5 0
mknod -m 600 console    c 5 1
mknod -m 755 ram0       b 1 0
mknod -m 755 ram1       b 1 1
mknod -m 755 ram2       b 1 2
mknod -m 755 ram3       b 1 3
mknod -m 755 ram4       b 1 4
mknod -m 660 loop0      b 7 0
mknod -m 660 loop1      b 7 1
mknod -m 660 loop2      b 7 2
mknod -m 660 loop3      b 7 3
mknod -m 644 crypto     c 10 70
mknod -m 644 cesa       c 10 71
mknod -m 660 rtc0       c 254 0

for i in $(seq 0 8)
do
mknod mtd$i c 90 $(expr $i + $i)
mknod mtdblock$i b 31 $i
done

mknod -m 660 fb0 c 29 0

mknod md0 b 9 0
mknod md1 b 9 1
mknod md2 b 9 2
mknod md3 b 9 3
mknod md4 b 9 4

mknod sg0 c 21 0
mknod sg1 c 21 1
mknod sg2 c 21 2
mknod sg3 c 21 3
mknod sg4 c 21 4
mknod sg5 c 21 5
mknod sg6 c 21 6
mknod sg7 c 21 7
mknod sg8 c 21 8
mknod sg9 c 21 9
mknod sg10 c 21 10
mknod sg11 c 21 11
mknod sg12 c 21 12
mknod sg13 c 21 13
mknod sg14 c 21 14
mknod sg15 c 21 15

mknod sr0 b 11 0
mknod sr1 b 11 1
mknod sr2 b 11 2
mknod sr3 b 11 3
mknod sr4 b 11 4
mknod sr5 b 11 5
mknod sr6 b 11 6
mknod sr7 b 11 7
mknod sr8 b 11 8
mknod sr9 b 11 9
mknod sr10 b 11 10
mknod sr11 b 11 11
mknod sr12 b 11 12
mknod sr13 b 11 13
mknod sr14 b 11 14
mknod sr15 b 11 15

mknod -m 666 ptmx       c 5 2

mknod ppp c 108 0

mknod fuse c 10 229

mkdir shm

#i2c
I2C_INDEX=(0 1 2)
for i in ${I2C_INDEX[@]}; do
        mknod -m 600 i2c$i c 89 $i
        mknod -m 600 i2c-$i c 89 $i
done

#for sshd
mknod ptyp0 c 2 0
mknod ptyp1 c 2 1
mknod ptyp2 c 2 2
mknod ttyp0 c 3 0
mknod ttyp1 c 3 1
mknod ttyp2 c 3 2

#pts
mkdir pts; cd pts
mknod -m 640 0          c 136 0
mknod -m 640 1          c 136 1
mknod -m 640 2          c 136 2
mknod -m 640 3          c 136 3
mknod -m 640 4          c 136 4
mknod -m 640 5          c 136 5
cd ..

mknod hiddev0   c 180 96
cd ..

cd ../../

exit 0
###############################################





2019年4月11日 星期四

Linux 進入rootfs之後,查詢u-boot bootcmd變數的方法

進入Kernel後,在檔案系統中,若想要查詢u-boot的bootcmd參數值,可以用下面的指令來查詢~

# cat /proc/cmdline


2019年4月2日 星期二

使用Linux dd command 清除硬碟的 partition table

假設有顆硬碟為 /dev/sda

使用下面指令可以清空硬碟的 partition table

dd if=/dev/zero of=/dev/sda bs=512 count=1

因為硬碟的partition table 通常放在 最前面的 512Byte 的地方

如果想把硬碟回到最初始的狀態,可以這樣作~