2010/08/03

轉載:thyme前輩所寫的:壓縮檔案系統

以下文章轉載自:

http://phorum.study-area.org/index.php/topic,30272.0.html
http://phorum.study-area.org/index.php/topic,30274.html
http://phorum.study-area.org/index.php/topic,30276.html
http://phorum.study-area.org/index.php/topic,30340.html

(一)=======================================================
這系列不知要放哪,先放在我自己的版就沒錯了。

「前言」

這個題目是不小心答應三子兄寫的,真正完整應該是如何製作嵌入式
Linux 的檔案系統,不過,我工作就跟嵌入式的有關,寫完整等於把
公司的東西搬出來了,當然,這些沒什麼機密可言,只是對老闆過意
不去罷了。

底下所談的內容,有心的話,在網路上一定可以找到,我只不過整理
一下,再加上一點點小小經驗罷了,嵌入式其實並不難,就看有沒有
經驗而已。

身在學園,那我從必要的明白的地方講起,以後才能舉一反三,太基
礎的就要自己去找資料了,假設程度都是會 Linux,鳥哥的書也看過,
看到不懂的指令有辦法去找出用法,沒有安裝的程式,也會自行安裝


「ISO9660」

首先,大家應該知道,Windows 有 FAT、NTFS,在 Linux 上常用的
是 EXT2 ,這些都是檔案系統,Unix 世界,和 Windows 有一點很大
不同,什麼都看成檔案系統,咦,這點好像大家都知道的嘛!知道歸
知道,腦中有沒這麼直覺就還不一定了。
舉個例子,有片光碟片,裡面都是資料,現在要把全部放入硬碟,以
方便隨時查閱,也會分享給別人看,甚至可能會全部 copy 給別人,
你會如何做?建一個目錄,全部 copy 進去,再用網路分享,有需要
的人,再用 ftp 來 copy?
我的話,會這麼做
程式碼:

# cat /dev/cdrom > /mnt/data.iso
# mount -t iso9660 -o loop /mnt/data.iso /mnt/data/

別人要的時候,就直接把 iso 檔給人,要燒光碟也方便。如果,你有
一個空的partition,比光碟容量大一點點,要全部放進去的話,我會這
麼做
程式碼:

# dd if=/mnt/data.iso of=/dev/hdax
# mount -t iso9660 /dev/hdax /mnt/data

很好玩吧!別被 C 槽、 D 槽的想法限制住唷!

這篇先講到這,咦,壓縮怎麼沒講?三子兄別急,一步一步來,沒這
麼快,我先去喝個水。

(二)======================================================
(範例程式所表示的目錄或device,僅供參考,可能不存在,
也不保証一定可執行)

「EXT2」

再來要熟悉一下怎麼做 ext2 的檔案系統
程式碼:

# mke2fs /dev/hdax
# mount -t ext2 /dev/hdax /mnt/tmp

咦,這好像太簡單了,沒錯,的確太簡單了,我們要談的不是這個。

程式碼:

#!/bin/sh
echo "create 4,096KB "
dd if=/dev/zero of=/tmp/tmp_loop bs=1k count=4096
losetup /dev/loop0 /tmp/tmp_loop
mke2fs -m 0 /dev/loop0
mount -t ext2 /dev/loop0 /mnt/tmp

這時候,你會發覺,在 /mnt/tmp 有 4MB 的空間可以寫入唷!
這有什麼用途呢?當然很有用,如果你有看過如何製作軟碟開機片,
一定會覺得很熟悉!

再來,把後面的尾巴完成
程式碼:

#!/bin/sh
#先把一些你需要的檔案copy進入 /mnt/tmp
umount /mnt/tmp
losetup -d /dev/loop0
echo "建立 ramdisk image : initrd.img"
dd conv=sync if=/tmp/tmp_loop | gzip -9 > /tmp/initrd.img.gz

如果你有把整個開機需要的檔放進去,那這個 image 就是可開機的
linux檔了。
要看內容怎麼辦?
程式碼:

# gunzip /tmp/initrd.img.gz
# mount -t ext2 -o loop /tmp/initrd.img /mnt/tmp

上面程式有看到 gzip ,好像有談到縮壓了,沒錯,這是很普通嵌入
式所應用的縮壓方式,但是,我們不用這個方式,因為,要應用時,
要先做一個 ramdisk ,然後把檔案 gunzip 到 ramdisk 上,才能使
用,有什麼缺點呢?舉個例子來說明,假設總共要8MB,縮壓後只要
4MB,你 flash 有 4MB 剛好放得下,記憶體有 16MB ,那開機後
要劃 8MB 的 ramdisk 給解開的檔案系統用,記憶體就憑空少了
8MB,所以這並不是一個很好的方法。當然,也有好處,一切唯讀,
隨便重開機也不會掛,重開機一切恢復正常。

(三)====================================================
「cramfs」

這篇是重點,也是最後一篇,這系列只能談到這兒了。
有沒有想過,為什麼一定要解開之後才能讀呢?不解直接讀,可行否?
是的,可以的,但檔案系統不同,有個檔案系統很符合--cramfs ,
程式碼:

# mkdir /tmp/tmp_root
# copy你所要的檔案到 /tmp/tmp_root
# mkcramfs /tmp/tmp_root.img /tmp/tmp_root
# mount -t cramfs -o loop /tmp/tmp_root.img /mnt/tmp

你會發覺,/mnt/tmp 和 /tmp/tmp_root 的內容是相同的,用 du 去查,
大小也差不多,但是,/tmp/tmp_root.img 的大小卻小很多,而且
也不用另外解開才能讀,不會另外再佔一個非壓縮的空間唷!
說明一下,mkcramfs 主要目的就是做一個壓縮的檔案系統,它做法是
直接把一個目錄轉成一個檔案系統,你可以直接做用 mount 的方式來
掛載,就如同前面的 iso9660 、 ext2 的使用方式。放入嵌入式系統
時,也不用另外再把有限的記憶體割一塊來放檔案系統了。另外,
你或許要重編 kernel 才可支援 cramfs。

這有什麼限制?當然有,最大限制就是,它是一個唯讀的,你對它寫
入是無效的,由於要即時解壓縮,效能上也會差一點點,但不會影響
很大。

那有沒有像 Windows 一樣的,可以對某些檔案、目錄壓縮,也可以
即時寫入的?有的,要 patch C library 及 Kernel。那怎麼用?很抱
歉,你問錯人了,我不會。


OK,結束,下課!

(四)=======================================================
咦,上篇不是說下課了嗎?沒錯,是下課了,這篇是課後輔導。

cramfs 不是萬能的,有一些很重要的限制要注意:
一、檔案最大限制為 16MB。
二、檔案系統最大上限為 256MB。
三、所有檔案的 timestamps 都是 1970/01/01 。
其他的請參考 kernel source 的文件 /usr/src/linux/Documentation/filesystems/cramfs.txt

(相關討論串)=================================================
hata:
用 squashfs 比較沒有限制,而且壓縮比較好。
siyou:
現在要算squashfs + lzma 最棒了.
squashfs default use gzip, but you can try to patch it to use lzma,
of course you have to change mksquashfs to use lzma too.

沒有留言:

ECSA 考試之後

今天通過了ECSA 考試,順利拿到證書。 但是70% 及格的考試,我是70.67 過關。 特定幾個領域的問題全部都不會,沒概念也答不出來。 還有一題,從題目到所有選項、都有看不懂的單字,到最後只能猜。因為從題目到四個選項,我都不知道在講什麼東西。 所以過了又如何,離開...