[技術] SquashFS

Written on 3:25 下午 by Yu Lai

其實Squashfs已經用一陣子了,在用它之前是使用initramfs。
和initramfs相比,Squashfs較不佔記憶體的空間,
因為它是可以跑在mtd上的唯讀型壓縮檔案系統。
但也因為是唯讀的,所以在使用上仍需另外配置ramfs來提供Linux使用。
另外,initramfs和Kernel是包成同一個image的,而Squashfs是分開的。

Squashfs是一套供Linux核心使用的GPL開源唯讀壓縮檔案系統。
Squashfs能夠為檔案系統內的檔案、inode及目錄結構進行壓縮,
並支援最大1024千位元組的區段,以提供更大的壓縮比,
標準版的Squashfs採用gzip的數據壓縮。

Squashfs可以至http://squashfs.sourceforge.net/下載。

目前最新的是4.1版,是提供給Linux Kernel 2.6.29版本使用。
若使用較舊版本的Linux Kernel,請改用3.4版本。

以下是安裝Note,寫的有點亂,請見諒。
另外可以參考SquashFS HOWTO

1. 裝Linux Kernel上SquashFS patch。
# cd /opt/linux-2.6.xx
# patch -p1 < /opt/squashfs/kernel-patches/linux-2.6.xx/squashfs3.4-patch

2. 修改MTD配置,在Flash上配置出Kernel和Squashfs的partition出來。
(在此共切4個Partition,分別是0-Bootloader, 1-Kernel, 2-Rootfs, 3-Other)
若已經調整好或是使用類似Redboot的fis,可跳過這段。

3. 編Linux Kernel。
# make distclean
# make mrproper
# make menuconfig
在File systems->Miscellaneous file systems將Squashed filesystem啟動(bundled with the kernel)。
# make

4. 編出SquashFS tools (mksquashfs)。
# cd /opt/squashfs/squashfs-tools
# make

5. 將root file system透過mksquashfs來產生image。
# mksquashfs ./root_file_system rootfs.bin

6. 在Loader上用tftp把rootfs.bin載入後燒錄到Partition Rootfs對應在Flash上的Address。
e.g. # flash 0x00100000 0x80100000

7. 修改kernel command line。
請改成 "console=ttyS0 root=/dev/mtdblock2 rootfstype=squashfs"

PS1:
在root file system裡的/etc/fstab裡可加入
ramfs /tmp ramfs defaults 0 0,避免Linux無寫入的File System可以使用。

PS2:
配合mtd,在Linux下亦可以透過mtd tools直接upgrade root file system。
# flash_eraseall /dev/mtd2
# flashcp -v rootfs.bin /dev/mtd2

[技術] coLinux安裝步驟

Written on 6:56 下午 by Yu Lai

之前就裝過coLinux來玩過了,但後來公司配了workstation裝了Linux,
工作上的使用也都移到那台去run,於是就把coLinux給移掉了,沒辦法,佔空間啊。
最近要出差到國外做function verify,需要邊改邊測,總不能叫我還帶台
workstation出國吧,所以又把coLinux給裝起來了。不過隨著新版本coLinux,
安裝和設定上有些微的不同,以下就是這次安裝的步驟,就當做筆記吧。


1. 下載coLinux
首先,到coLinux的官網 http://www.colinux.org/ 下載最新的 coLinux,
點選download後它會幫你導向sourceforge,我抓到的版本為 0.7.4 版本。
這裡順便把coLinux幫我們包好的各大Linux Distribution的filesystem image
檔也抓下來,我使用的是 Debian-5.0r2-lenny.7z。

2. 安裝coLinux
抓完後執行解開,基本上照著點下一步就ok了。另外,TAP Driver記得安裝唷。
裝好後先別急著執行 coLinux,先把剛才的 Debian-5.0r2-lenny.7z 解開放在
coLinux的目錄下。

3. 網路設定-Windows
修改debian-lenny.conf的內容,把網路介面設成 eth0=tuntap。
(這一步看個人使用習慣,我是習慣透過tap配合NAT來使用。)
點選控制台->網路連線,把新增出來的網路介面名稱改為"TAP"方便示別。
接著點入原有的LAN的介面->內容->進階,把"允許其他網路使用著透過這台..."打勾,
開啟NAT的服務。

4. 網路設定-Debian
接著回到coLinux的目錄下執行debian-lenny.bat。
進到Debian的console後,用預設帳密 root / colinux 登入。先設定網路,
修改/etc/network/interfaces,把eth0的部份改為以下:

allow-hotplug eth0
iface eth0 inet static
address 192.168.0.100
netmask 255.255.255.0
gateway 192.168.0.1

修改/etc/resolv.conf,加入DNS:
nameserver 168.95.192.1

這裡補充一點,到/etc/modprobe.d/aliases把ipv6 Module給取消掉,
因為ipv6會影響到samba的運作,所以要修改一下:
alias net-pf-10 off

把以上這行取代掉原本的alias net-pf-10 ipv6即可。

5. 安裝Tools
再來就可以透過apt-get這個好用的tool把該裝的裝一裝了,
e.g. sshd, samba, gcc, subversion...etc。
這裡建議先裝前2個,這樣可以透過putty連進去,畫面操作上會比較順手。

6. 增加Partition
另外,由於我們的Partition是使用別人幫我們包好的filesystem image檔,
大小是固定的2gb。使用上多少會有所限制,所以這時可以透過以下方法新增
出額外的image檔來使用。
首先,在coLinux目錄下使用windows內建的指令來新增一空白的檔案:
c:\coLinux>fsutil file createnew Debian-pub.ext3.8gb 8589934592

這裡我建了一個8gb大小的檔案出來。
接著修改debian-lenny.conf的內容,把這個image檔mount進去,在conf檔內加入:
cobd1="Debian-pub.ext3.8gb"

改完後存檔,重新啟動coLinux,進到debian後,使用以下指令來建立ext3 filesystem:
debian# mkfs.ext3 /dev/cobd1

跑完後就可以mount啦,記得修改一下/etc/fstab把新的filesystem image自動mount起來:
/dev/cobd1      /pub            ext3    errors=remount-ro 0       1


7. 總結
以上就是這次安裝的一些重要步驟,至於其他Debian設定上的細節就沒提到了。
有什麼問題再寫E-mail問我吧。

[技術] 在C中列出目錄與檔案

Written on 8:50 上午 by Yu Lai

一般在C中,我們可以使用opendir()與readdir()來列出目錄下所有的檔案。
以下是範例程式:

#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>

main() {
DIR * dir;
struct dirent * ptr;
int i;
dir =opendir(“/etc/rc.d”);
while((ptr = readdir(dir))!=NULL) {
printf(“d_name: %s\n”,ptr->d_name);
}
closedir(dir);
}

配合struct dirent,定義如下:
struct dirent {
ino_t d_ino;
off_t d_off;
unsigned short int d_reclen;
unsigned char d_type;
char d_name[256];
};

d_ino 此目錄進入點的inode
d_off 目錄文件開頭至此目錄進入點的位移
d_reclen d_name的長度,不包含NULL字符
d_type d_name所指的檔案類型
d_name 檔名
其中unsigned cahr d_type;可以來判斷是子目錄或是一般的檔案。
但不知是我使用的uClibC的問題,沒實作到還怎樣,使用上一直有問題。

後來還是找到解決方法,方法有2種,分別如下:
1. 再使用一次readdir()來判斷回傳值,若回傳為NULL,即為檔案。
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>

main() {
DIR * dir;
DIR * dir2;
struct dirent * ptr;
int i;
dir =opendir(“/etc/rc.d”);
while((ptr = readdir(dir))!=NULL) {
char pathname[100];
sprintf(pathname,"/etc/rc.d/%s", ptr->d_name);
if((dir2 = opendir(pathname))==NULL) {
printf("%s: file\n", ptr->d_name);
} else {
printf("%s: directory\n", ptr->d_name);
closedir(dir2);
}
}
closedir(dir);
}

2. 使用int stat(const char *file_name, struct stat *buf),
在struct stat其中的 st_mode 可以用來判斷是哪種檔案(也就是上面 d_type的 功用)。
為了方便,POSIX另外有定義幾個MACRO:
S_ISLNK(st_mode) : 是symbolic link
S_ISREG(st_mode) 一般檔案(regular file)
S_ISDIR(st_mode) 目錄(directory)
S_ISCHR(st_mode) 字元設備檔(char device)
S_ISBLK(st_mode) 區塊設備檔(block device)
S_ISSOCK(st_mode) local-domain socket
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>

main() {
DIR * dir;
struct dirent * ptr;
int i;
dir =opendir(“/etc/rc.d”);
while((ptr = readdir(dir))!=NULL) {
char pathname[100];
struct stat buf;
sprintf(pathname,"/etc/rc.d/%s", ptr->d_name);
stat(pathname, &buf);
if(S_ISREG(buf.st_mode))
printf("%s: file\n", ptr->d_name);
else
printf("%s: directory\n", ptr->d_name);
}
closedir(dir);
}

[技術] 嵌入式linux下常見的文件系統

Written on 2:14 下午 by Yu Lai

嵌入式linux下常見的文件系統
• RomFS:只讀文件系統,可以放在ROM空間,也可以在系統的RAM中,嵌入式linux中常用來作根文件系統
• RamFS:利用VFS自身結構而形成的內存文件系統,使用系統的RAM空間
• JFFS/JFFS2:為Flash設計的日誌文件系統
• Yaffs:專門為Nand Flash設計
• proc:為Kernel和Module將Message發送給Process提供一種機制,可以查看系統Module裝載的信息
• devFS:設備文件系統

Linux上的Ext2fs
• 支持4 TB存儲、文件名稱最長1012字符
• 可選擇邏輯塊
• 快速符號鏈接
• Ext2不適合flash設備
• 是為象IDE 設備那樣的塊設備設計的,邏輯塊大小必須是512 byte、1 KB、2KB等
• 沒有提供對基於扇區的擦除/寫操作的良好管理
• 如果在一個扇區中擦除單個字節,必須將整個扇區複製到RAM,然後擦除,再重寫入
• 在出現電源故障時,Ext2fs 是不能防止崩潰的
• 文件系統不支持損耗平衡,縮短了flash的壽命

jffs/jffs2文件系統的優缺點
• 日誌文件系統
• 提供了更好的崩潰、掉電安全保護
• jffs2支持對flash的均勻磨損
• 在扇區級別上執行閃存擦除/寫/讀操作要比Ext2文件系統好
• 文件系統接近滿時,JFFS2 會大大放慢運行速度——垃圾收集

Nand上yaffs文件系統的優勢
• 專門為Nand flash設計的日誌文件系統
• jffs/jffs2不適合大容量的Nand flash
• jffs的日誌通過jffs_node建立在RAM中,佔用RAM空間:對於128MB的Nand大概需要4MB的空間來維護節點
• 啟動的時候需要掃瞄日誌節點,不適合大容量的Nand flash
• FAT系統沒有日誌編譯yaffs文件系統
• mtd的最新補丁升級?
• 接口更新,適合與yaffs
• 與原有的mtd驅動程序不兼容,需要重寫
• 如果使用舊mtd驅動需要定義Makefile中MTD_OLD = -DCONFIG_YAFFS_USE_OLD_MTD
• 參考文檔: yaffs-rootfs-howto
• 最新版的yaffs網站:
http://www.aleph1.co.uk/armlinux/projects/yaffs

使用yaffs文件系統
• 通過cat /proc/yaffs命令可以看到yaffs系統的相關信息
• mount -t yaffs /dev/mtdblock/0 /mnt/yaffs

[技術] 解決samba的charset問題

Written on 11:28 上午 by Yu Lai

就在9/11那天所po的"[技術] 在FreeBSD上掛載smbfs"中,其實有個問題沒有被提到,而是最近才解決的,那就是charset的問題。

在那台Linux上是採用zh_TW.Big5的編碼,其檔案系統也是採用Big5來儲存檔名。而在FreeBSD那台是採用zh_TW.UTF-8,自然的透過mount_smbfs來掛載會出現亂碼的問題,在經過測試,發現mount_smbfs -E的選項可說是無效..XD

所幸,解決的方法是根據samba的The Official Samba-3 HOWTO and Reference Guide中的
Chapter 30. Unicode/Charsets裡提到的:
As of Samba-3, Samba can (and will) talk Unicode over the wire. Internally, Samba knows of three kinds of character sets:

unix charset
This is the charset used internally by your operating system. The default is UTF-8, which is fine for most systems and covers all characters in all languages. The default in previous Samba releases was to save filenames in the encoding of the clients for example, CP850 for Western European countries.

display charset
This is the charset Samba uses to print messages on your screen. It should generally be the same as the unix charset.

dos charset
This is the charset Samba uses when communicating with DOS and Windows 9x/Me clients. It will talk Unicode to all newer clients. The default depends on the charsets you have installed on your system. Run testparm -v | grep "dos charset" to see what the default is on your system.

也就是只要將unix charset和display charset皆設為配合系統設定的Big5的CP950,然後在dos charset設為UTF-8,這樣透過mount_smbfs來掛載時就會自動轉成UTF-8的編碼了。而目前的成果自然就是FreeBSD上的pure-ftp (with utf-8 support)可以多很多東西囉。

[技術] 在FreeBSD上掛載smbfs

Written on 12:36 上午 by Yu Lai

最近,在弄lab的ftp整合計畫。
要將另一台Linux的資料透過samba的方式來掛載到ftp那台FreeBSD上。
以下則是在弄的過程所得到的一些Notes。

首先,我們可以透過以下的指令來察看有提供連線的資料
smbutil view

掛載時則使用
mount_smbfs //[username]@[host]/[service] [mountpoint]

若要加入 /etc/fstab 使開機後自動mount,請先編輯 /etc/nsmb.conf
加入[host:user]的 section,注意! host及section都必須為"大寫",既使平常輸入的是小寫!
然後在該section加入
password=[encrypted_password] (由smbutil crypt算出)

最後,在 /etc/fstab 裡加上:
//[username]@[host]/[service] [mountpoint] smbfs rw,-I=xxx.xxx.xxx.xxx,-N,-u=[uid],-g=[gid] 0 0

要測試是否成功可以用:
mount -a
來觀看結果。

[技術] 在Linux上掛載FreeBSD的UFS

Written on 6:19 下午 by Yu Lai

Linux從Kernel 2.6.x開始對FreeBSD的UFS有著良好的支援,
對於FreeBSD的Slice也可以對應良好,但在mount時有些參數
仍需注意一下。

以下是在Linux上要mount UFS的一些注意的地方:
首先先用dmesg找到UFS所在的device node,
e.g.
hdc: ST380021A, ATA DISK drivehdc: max request size: 128KiB
hdc: 156312576 sectors (80032 MB) w/2048KiB Cache, CHS=65535/16/63, UDMA(33)
hdc: hdc1
hdc1: <bsd: hdc5 hdc6 hdc7 hdc8 hdc9 >
然後再執行mount指令來掛載ufs,因為要掛載slice,所以要在options中加入ufstype=ufs2。
# mount -t ufs -o ufstype=ufs2,ro /dev/hdc9 /mnt