轉載: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.

留言

這個網誌中的熱門文章

ISO 27001 上課和考試心得

ECSA 考試之後

賭場玩骰子的技巧 - 原理篇 - 機率