顯示具有 dd 標籤的文章。 顯示所有文章
顯示具有 dd 標籤的文章。 顯示所有文章

2013年1月17日 星期四

如何建立 Raspberry Pi SD Card

1. 下載 2013-02-09-wheezy-raspbian.zip
  a. 從官方網站下載 - http://www.raspberrypi.org/downloads
  b. 從我的映像站下載

2. 解開 2013-02-09-wheezy-raspbian.zip

unzip 2013-02-09-wheezy-raspbian.zip

此時會解開出一個 2013-02-09-wheezy-raspbian.img 的影像檔,我們可以使用之前所介紹掛載 sdcard.img 的方式來掛載此檔以觀察其內容。

3. 掛載 2013-02-09-wheezy-raspbian.img 檔案

a. 請先切換至 root 權限 (su)

b. # losetup /dev/loop0 2013-02-09-wheezy-raspbian.img

   此指令是將 2013-02-09-wheezy-raspbian.img "連接" 至 /dev/loop0 這個裝置

   # losetup -a -> 觀察連接的結果,其輸出如下:

/dev/loop0: [0805]:999425 (/home/herman/raspberry/2013-02-09-wheezy-raspbian.img)

我們可以得知 /dev/loop0 已經跟 2013-02-09-wheezy-raspbian.img 連接在一起。接著我們可以執行 fdisk -lu 來觀察 /dev/loop0 這個裝置,請執行底下指令:

   # fdisk -lu /dev/loop0

其輸出如下:

Disk /dev/loop0: 1939 MB, 1939865600 bytes
255 heads, 63 sectors/track, 235 cylinders, total 3788800 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00017b69

      Device Boot      Start         End      Blocks   Id  System
/dev/loop0p1            8192      122879       57344    c  W95 FAT32 (LBA)
Partition 1 does not end on cylinder boundary.
/dev/loop0p2          122880     3788799     1832960   83  Linux
Partition 2 does not end on cylinder boundary.

c. 將 2013-02-09-wheezy-raspbian.img 的第一分割區"連接"至 /dev/loop1,其指令如下:

losetup -o `expr 8192 \* 512` /dev/loop1 /dev/loop0

我們可以執行 losetup -a 來觀察連接結果,其輸出如下:

/dev/loop0: [0805]:999425 (/home/herman/raspberry/2013-02-09-wheezy-raspbian.img)
/dev/loop1: [0005]:1312 (/dev/loop0), offset 4194304

接著將 2013-02-09-wheezy-raspbian.img 的第二分割區"連接"至 /dev/loop2,其指令如下:

losetup -o `expr 122880 \* 512` /dev/loop2 /dev/loop0

我們可以執行 losetup -a 來觀察連接結果,其輸出如下:

/dev/loop0: [0805]:999425 (/home/herman/raspberry/2013-02-09-wheezy-raspbian.img)
/dev/loop1: [0005]:1312 (/dev/loop0), offset 4194304
/dev/loop2: [0005]:1312 (/dev/loop0), offset 62914560

這表示 /dev/loop1 及 /dev/loop2 都連接至正確的分割區,接著就可以進行掛載。

d. 將 /dev/loop1 掛載至 /mnt/sdcard1 目錄


#  mount /dev/loop1 /mnt/sdcard1

將 /dev/loop2 掛載至 /mnt/sdcard2 目錄

#  mount /dev/loop2 /mnt/sdcard2

若無 /mnt/sdcard1 /mnt/sdcard2 目錄的話,請先執行底下建立:

#   mkdir -p /mnt/sdcard1 /mnt/sdcard2

掛載完後請執行 df -h 來觀察是否已掛載成功,其輸出如下:

檔案系統              Size  Used Avail Use% 掛載點
/dev/loop1             56M   17M   40M  30% /mnt/sdcard1
/dev/loop2            1.8G  1.4G  315M  82% /mnt/sdcard2


e. 切換至 /mnt/sdcard1 /mnt/sdcard2 目錄來觀察其內容。

   cd /mnt/sdcard1
   ls -l

   我們可以看到此分割區為 bootloader 及 kernel 之目錄,其輸出如下:
-rwxr-xr-x 1 root root   17764 2012-10-29 01:40 bootcode.bin
-rwxr-xr-x 1 root root     142 2012-12-16 01:43 cmdline.txt
-rwxr-xr-x 1 root root    1180 2012-12-16 01:43 config.txt
-rwxr-xr-x 1 root root    2020 2012-10-29 01:40 fixup_cd.dat
-rwxr-xr-x 1 root root    5282 2012-10-29 01:40 fixup.dat
-rwxr-xr-x 1 root root     137 2012-12-17 03:51 issue.txt
-rwxr-xr-x 1 root root 2104952 2012-10-29 01:40 kernel_cutdown.img
-rwxr-xr-x 1 root root 9522048 2012-10-29 01:40 kernel_emergency.img
-rwxr-xr-x 1 root root 2695192 2012-10-29 01:40 kernel.img
-rwxr-xr-x 1 root root  523144 2012-10-29 01:40 start_cd.elf
-rwxr-xr-x 1 root root 2347828 2012-10-29 01:40 start.elf

   cd /mnt/sdcard2
   ls -l

我們可以看到此分割區為 rootfs 之目錄,其輸出如下:

drwxr-xr-x  2 root root  4096 2012-12-16 02:16 bin
drwxr-xr-x  2 root root  4096 2012-12-16 01:43 boot
drwxr-xr-x  3 root root  4096 2012-12-16 02:16 dev
drwxr-xr-x 95 root root  4096 2012-12-17 03:39 etc
drwxr-xr-x  3 root root  4096 2012-12-17 03:39 home
drwxr-xr-x 12 root root  4096 2012-12-16 02:05 lib
drwx------  2 root root 16384 2012-12-16 01:28 lost+found
drwxr-xr-x  2 root root  4096 2012-12-16 01:31 media
drwxr-xr-x  2 root root  4096 2012-09-03 01:08 mnt
drwxr-xr-x  3 root root  4096 2012-12-16 01:42 opt
drwxr-xr-x  2 root root  4096 2012-09-03 01:08 proc
drwx------  2 root root  4096 2012-12-16 01:31 root
drwxr-xr-x  7 root root  4096 2012-12-17 03:37 run
drwxr-xr-x  2 root root  4096 2012-12-16 02:16 sbin
drwxr-xr-x  2 root root  4096 2012-06-20 17:23 selinux
drwxr-xr-x  2 root root  4096 2012-12-16 01:31 srv
drwxr-xr-x  2 root root  4096 2012-11-27 17:13 sys
drwxrwxrwt  2 root root  4096 2012-09-03 01:08 tmp
drwxr-xr-x 10 root root  4096 2012-12-16 01:31 usr
drwxr-xr-x 11 root root  4096 2012-12-16 01:31 var

4. 解除掛載

a. 解除掛載 目錄

   # umount /mnt/sdcard1
   # umount /mnt/sdcard2
   使用 df -h 來觀察是否已解除掛載

b. 解除 loop 連接

   # losetup -d /dev/loop2
   # losetup -d /dev/loop1
   # losetup -d /dev/loop0

   使用 losetup -a 來觀察是否已解除連接




** 將 2013-02-09-wheezy-raspbian.img 下載至 sdcard **

1. 首先將 SD card 放入讀卡機,並接上電腦,然後執行 dmesg 觀察最後面輸出之
   SD card 的代號,例如:

[11237833.478264] sd 4:0:0:0: [sdb] 7673856 512-byte logical blocks: (3.92 GB/3.65 GiB)
[11237833.478885] sd 4:0:0:1: [sdc] Attached SCSI removable disk
[11237833.479635] sd 4:0:0:2: [sdd] Attached SCSI removable disk
[11237833.480265] sd 4:0:0:3: [sde] Attached SCSI removable disk
[11237833.481313] sd 4:0:0:0: [sdb] Write Protect is off
[11237833.481317] sd 4:0:0:0: [sdb] Mode Sense: 03 00 00 00
[11237833.482161] sd 4:0:0:0: [sdb] No Caching mode page present
[11237833.482165] sd 4:0:0:0: [sdb] Assuming drive cache: write through
[11237833.486012] sd 4:0:0:0: [sdb] No Caching mode page present
[11237833.486017] sd 4:0:0:0: [sdb] Assuming drive cache: write through
[11237833.488435]  sdb: sdb1 sdb2
[11237833.491524] sd 4:0:0:0: [sdb] No Caching mode page present
[11237833.491529] sd 4:0:0:0: [sdb] Assuming drive cache: write through
[11237833.491533] sd 4:0:0:0: [sdb] Attached SCSI removable disk

從上面訊息我們可以得知 SD card 是 /dev/sdb 這個裝置,其容量為 3.92 GB = 4 GB

2. 將 2013-02-09-wheezy-raspbian.img 植入 SD card
   請先切換至 root 權限,再執行:

   # dd if=2013-02-09-wheezy-raspbian.img of=/dev/sdb bs=1024k

   經過 N 分鐘後會完成植入流程,N 自 5 ~ 8 不等,看記憶卡的速度。執行完畢後之輸出如下:

1850+0 records in
1850+0 records out
1939865600 bytes (1.9 GB) copied, 656.276 s, 3.0 MB/s



3. 掛載實體 SD card

# mount /dev/sdb1 /mnt/sdcard1
# mount /dev/sdb2 /mnt/sdcard2

使用 df -h 來觀察其輸出,如下所示:

檔案系統              Size  Used Avail Use% 掛載點
/dev/sdb1              56M   17M   40M  30% /mnt/sdcard1
/dev/sdb2             1.8G  1.4G  315M  82% /mnt/sdcard2

4. 觀察 SD card

   cd /mnt/sdcard1 目錄觀察
   cd /mnt/sdcard2 目錄觀察



5. 修改開機參數

   cd /mnt/sdcard1
   vi config.txt

   將
#hdmi_safe=1 改為
hdmi_safe=1

接著我們就可以拿 SD card 至 raspberry pi 板子上開機。

2012年10月17日 星期三

如何建立虛擬 SD card

#2020/04/20 改版

如何建立虛擬 SD card


0. 目標:建立一個 sdcard.img,將其分割為二個分割區

part1: 80 M
part2: 920 M

並將第一個分割區以 vfat 方式格式化,第二個分割區以 ext4 方式格式化,而且兩個分割區都要能掛載。


1. 使用 dd 指令建立 1G 之 sdcard.img

dd if=/dev/zero of=sdcard.img bs=1M count=1024

作完後之輸出如下所示:

1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 17.8515 s, 60.1 MB/s

我們可以使用 file 及 hexdump 這兩個指令來檢視 sdcard.img,其操作如下:

file sdcard.img

其輸出為:

sdcard.img: data

hexdump sdcard.img

其輸出為:

0000000 0000 0000 0000 0000 0000 0000 0000 0000
*
40000000

以上輸出表示此檔案之內容為 00 (也就是 ASCII 表中之 Null 字元),其位址從 0x0000000 一直至 0x40000000 也就是 1G。

到此為止,我們已完成一個空的 sdcard.img。接著我們要使用 losetup 來連接此檔案至 /dev/loop0 裝置以便進行分割及格式化。

2. 使用 losetup 指令

要使用 losetup 指令,請先切換至 root 權限,我們先看目前是否有 /dev/loop 裝置,其指令如下所示:

# losetup -a

理論上目前沒有任何輸出。接著請執行底下指令將 /dev/loop0 與 sdcard.img 「連接」在一起。

# losetup /dev/loop0 sdcard.img

此時我們即將 sdcard.img 「連接」至 /dev/loop0 這個裝置。


3. 使用 fdisk 分割 /dev/loop0

將第一個分割區切成 80 MB
將第二個分割區切成剩下空間 (920 MB)

作完後將分割區狀況存入並退出 fdisk,我們可以執行底下指令來觀看 /dev/loop0 狀態。

fdisk -lu /dev/loop0

其輸出如下所示:

# fdisk -lu /dev/loop0
Disk /dev/loop0: 1 GiB, 1073741824 bytes, 2097152 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xa5e072a5

Device       Boot  Start     End Sectors  Size Id Type
/dev/loop0p1        2048  165887  163840   80M  b W95 FAT32
/dev/loop0p2      165888 2097151 1931264  943M 83 Linux


在存分割表 (w 指令)時如果出現底下訊息要將 /dev/loop0 與 sdcard.img 分離,再重新連接才可以繼續往下作。

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: Re-reading the partition table failed with error 22: 不適用的引數.
The kernel still uses the old table. The new table will be used at
the next reboot or after you run partprobe(8) or kpartx(8)
Syncing disks.


** 使用 losetup 將 /dev/loop0 與 sdcard.img 分離 **

# losetup -d /dev/loop0

我們可以執行 losetup -a 來看是否已解除連接。若要重新連接請執行以下指令:

# losetup /dev/loop0 sdcard.img

連接完可以執行

fdisk -lu /dev/loop0

來觀察其輸出是否如上所示。

4. 格式化/掛載/解掛/解除連結

4.1 格式化與掛載

我們統一將第 1 個分割區格式化為 fat 格式,第 2 個分割區格式化為 ext4 格式以便 u-boot 載入系統核心並掛載 rootfs。在格式化前我們需注意每一個分割區的 sector 數目,例如第 1 個分割區的 Sectors 為 163840,而第 2 個分割區則為 1931264。這兩個數字將分別應用在格式化上,但是在格式化前,我們要將第 1 個分割區連接至 /dev/loop1,第 2 個分割區連接至 /dev/loop2,請執行底下指令連接 /dev/loop1:

losetup -o `expr 2048 \* 512` /dev/loop1 /dev/loop0

接著再執行底下指令連接 /dev/loop2:

losetup -o `expr 165888 \* 512` /dev/loop2 /dev/loop0

上述指令都有使用到 expr 這個命令,expr 可以拿來作簡單的四則運算,例如:

expr 1 + 1 其輸出為 2
expr 2 - 1 其輸出為 1

但若要進行乘法的話必須使用 \* 而非 *,因為 * 是特殊字元。

expr 2 * 3 -> expr: 格式錯誤
expr 2 \* 3 -> 6

至於除法範例如下:

expr 6 / 2 -> 2
expr 6 / 4 -> 1 (沒有餘數)

`expr a \* b` 表示「傳回」 a * b 之值。

當我們要連接 /dev/loop1 (第 1 個分割區) 及 /dev/loop2 (第 2 個分割區)時,必須跳過相對應的 offset,這個 offset 就由 expr 來替我們作運算。當 /dev/loop1 及 /dev/loop2 都連接上時,我們可以執行:

losetup -a

此時會出現底下輸出,告訴我們 /dev/loop1 及 /dev/loop2 都完成連接。

/dev/loop0: [0805]:2540233 (/home/herman/qemu_image/arm/sdcard.img)
/dev/loop1: [0005]:1312 (/dev/loop0), offset 32256
/dev/loop2: [0005]:1312 (/dev/loop0), offset 90478080

接著我們即可真正對 /dev/loop1 及 /dev/loop2 進行格式化:

mkfs.msdos -s 2 /dev/loop1 81920

mkfs.ext4 /dev/loop2 965632    -> 此指令不用,以免 u-boot 無法掛載

mkfs.ext4 -O ^metadata_csum,^64bit /dev/loop2  -> 改用這個指令來分割虛擬 sdcard

格式化完畢後我們可以進行掛載以便待會複製檔案,我們統一掛載至

/mnt/sdcard1 及 /mnt/sdcard2 目錄。

Q: 若以上兩個目錄不存在,該如何建立 ?

mkdir -p /mnt/sdcard1 /mnt/sdcard2


建好目錄後可以進行掛載,指令如下:

mount /dev/loop1 /mnt/sdcard1
mount /dev/loop2 /mnt/sdcard2

我們可以執行 df -h 來檢查是否有正確掛載,其輸出如下:

檔案系統              Size  Used Avail Use% 掛載點
/dev/loop1             87M     0   87M   0% /mnt/sdcard1
/dev/loop2            919M   18M  855M   2% /mnt/sdcard2

接下來,我們可以針對虛擬 SDCARD 開始複製檔案以便使用 Qemu 開機模擬。

4.2 解掛

4.2.1 解掛目錄

# umount /mnt/sdcard1 /mnt/sdcard2

4.2.2 解掛 loop,注意:順序要跟掛 loop 反過來作。

# losetup -d /dev/loop2
# losetup -d /dev/loop1
# losetup -d /dev/loop0

檢查是否完全解開:

# losetup -a


5. 植入 bootloader、kernel 以及 rootfs

5.1 bootloader 所需檔案

MLO
u-boot
u-boot.bin
u-boot.img
uEnv.txt        -> 開機設定檔

5.2 kernel 所需檔案

uImage

請將上述檔案複製至 /mnt/sdcard1 目錄


5.3 如何建立 rootfs

Q: 請問什麼是 rootfs ?
a. 最簡單的作法:將 qemu 中的 rootfs 拿來改,但是要記得瘦身。

b. 另一個簡單的作法:拿現成的來用,網路上有一位高手叫 Robert Nelson,
他所提供的下載網址在:


http://rcn-ee.net/deb/minfs/

目前最新的下載檔案是:

http://rcn-ee.net/deb/minfs/wheezy/debian-7.7-minimal-armel-2014-11-10.tar.xz
c. 修改 rootfs

要將 rootfs 植入 /mnt/sdcard2 中請完成底下工作:

c.1 將 rootfs 存入 /mnt/sdcard2
c.2 將核心模組存入 /mnt/sdcard2/lib/modules 目錄
c.3 修改設定檔,修改內容如下:

c.3.a 將 /etc/inittab 存入 /mnt/sdcard2/etc 中,並將最後一行改為
T2:23:respawn:/sbin/getty -L ttyO2 115200 vt102

c.3.b 將 /mnt/sdcard2/etc/fstab 修改如下:
proc             /proc proc defaults           0 0
/dev/mmcblk0p2   /     auto errors=remount-ro  0 1
/dev/mmcblk0p1   /boot auto defaults           0 0

c.3.c 將 /mnt/sdcard2/etc/network/interfaces 修改如下:
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp

c.3.d 將 /etc/sdcard2/etc/hostname 修改如下:
leenix

c.3.e 將 /etc/resolv.conf 修改如下:
nameserver 8.8.8.8

6. 當所有檔案完成複製後,我們必須將 sdcard.img 解除掛載及解除連接,請執行以下指令:

umount /mnt/sdcard1 /mnt/sdcard2 -> 先解除目錄掛載

losetup -d /dev/loop2   -> 再依順序解除 loop 連接,請依後進先出的原則來解除
losetup -d /dev/loop1
losetup -d /dev/loop0   -> 至此全部解除連接,我們可以執行

losetup -a 來確認。


7. 測試虛擬 sdcard.img

當我們都完成檔案複製後,我們可以使用 qemu 來測試所完成之虛擬 sdcard.img,測試指令如下:

 qemu-system-arm -M beagle -m 512 -nographic -sd ./test.img -clock unix \
        -device usb-mouse -device usb-kbd \
        -usb -device usb-net,netdev=mynet -netdev user,id=mynet