2008年10月22日 星期三

Linux 使用 USB 裝置筆記

USB規格簡介

USB Univeral Serial Bus (通用串列匯流排),常見的外部匯流排,支援熱插拔 (hot plugable),一個 USB 最多可以連接127個裝置。

目前規格包括:

1.USB 1.1 支援二種傳輸速率:Low speed - 1.5 Mbps 及 Full Speed - 12 Mbps。
2.USB 2.0 傳輸速率 480 Mbps 並支援 USB 1.1。

USB 採用 Single-Master (單主控) 設計,線路架構就像多個點對點的樹狀結構,具 USB 介面的 PC 至少有一個 "root hub",並提供二個外接孔供 USB 設備或另一個 USB hub。在電腦中的 USB 主控器會去 poll USB 匯流排上的各個裝置,每個 USB 設備連接到主機時,USB 主控器會分配一個代碼給該裝置,並讀取該裝置的描述表 (Device Descriptor) 以獲知裝置的硬體資訊。

USB 主控器(USB hoot Controller) 分為三種規格:

1.OHCI (Open Host Controller Interface):USB 1.1 規格,Compaq(康柏)公司主導, 使用廠商包括 Compaq、iMacs、OPTi、SIS、ALi,採用 Memory-mapped 的 I/O 方式 (CPU 使用記憶體指令來存取 USB 主控器)。
2.UHCI (Universal Host Controller Interface) :USB 1.1 規格,Intel公司提倡, 線路比 OHCI 線路簡單,但是需要比較複雜的驅動程式,對CPU負擔也微重了些,使用廠商包括 Intel、VIA,採用 I/O-mapped 的 I/O 方式 (CPU 使用 I/O 指令來存取 USB 主控器)。
3.EHCI (Enhanced Host Controller Interface):USB 2.0 規格,速度較快 (480 Mbps),支援 USB 1.1,相容於 OHCI 和 UHCI。


Linux 對 USB的支援

Linux 從 kernel 2.2.7 版本便開始支援 USB,USB 2.0 是從 2.4.19 開始, Linux 以三層式架構來支援 USB 系統,這三層是內核層 (Core) 、主控層 (Controller)、裝置層 (Device)。內核層指的是 kernel 對 USB 系統的支援,主控層對應到不同規格的 USB 主控器,連接 USB 設備時不必考慮主控器的規格,裝置層的設定,依裝置類型會有所不同。


Linux USB 驅動程式共有三種不同的 USB 主控制器選項,因為在主板和 PCI 卡上有三種不同類型的 USB 控制晶片。


1.EHCI (ehci-hcd.o) :USB 2.0 協定的晶片。
2.OHCI (usb-ohci.o) :非 PC 系統上的(以及帶有 SiS 和 ALi 晶片組的 PC 主板上的)USB 晶片。
3.UHCI (usb-uhci.o) :大部份 PC 主機板(包括 Intel 和 Via)。


在 Linux 下可查詢 /proc/pci 所記錄的 PCI 子系統資源配置情況,或指令 lspci,從中分辦出 USB 主控器屬於那種規格,只需載入 USB 類型對應的 ?HCI 驅動程式即可,若單獨載入 EHCI 不行,則根據主板類型載入UHCI 或 OHCI 後,再載入EHCI。

使用 usbmodules 指令可查詢己連接至系統的 USB 裝置有那些可以使用的核心驅動模組,在載入/卸載核心模組會利用到 usbmodules 程式,利用 hotplug 或 usbmgr 程式可以在 USB 裝置與電腦連接/移除時,自動載入/卸載核心模組、執行相關 Scripts。

Linux 相關的指令和檔案:

mount none /proc/bus/usb -t usbdevfs
usbmodules
hotplug
usbmgr
/etc/usbmgr/
/etc/hotplug/

Linux 對應USB設備一些常用必要的驅動程式模組:

usbcore.o:支援usb所需要的最基礎模組。
usb-uhci.o / usb-ohci.o / ehci-hcd.o:USB 控制晶片驅動程式。
uhci.o :另一個uhci驅動程式,一般不需載入,可能會當機。
hid.o:USB人機界面設備,如滑鼠、鍵盤。
usbmouse.o:USB滑鼠(還需再載入mousedev.o)。
usbkbd.o:USB鍵盤(還需再載入keybdev.o)。
usb-storage.o:USB 存儲設備,Flash Disk 等。
usbnet.o:USB並聯線,讓兩部電腦資料透過USB傳輸。

Linux 相關驅動程式模組:

ide-disk.o :IDE硬碟。
ide-scsi.o :把IDE設備類比SCSI介面。
scsi_mod.o:SCSI 裝置。
sd_mod.o:SCSI硬碟。
sr_mod.o:SCSI光碟機。
sg.o:SCSI 一般裝置,在某些 Flash Disk、SCSI裝置偵測中會使用到。

Linux 使用 Flash Disk 需要載入的模組:

1.usbcore
2.usb-uhci / usb-ohci / ehci-hcd
3.scsi_mod
4.sd_mod
5.usb-storage

轉貼: Yu-Min Space 位於
http://yu-minspace.blogspot.com/2007/05/usb-usb-univeral-serial-bus-hot.html

2008年6月9日 星期一

請不要用 Foxy !


誠摯的建議您,Foxy 少用。


1. 有病毒

2. 很耗資源 (不管是 CPU 或者是 網路頻寬)

3. 很消耗硬體


說實在,以前我在管系實驗室時,最討厭就是學長或學弟在裡面放 Foxy。更討厭女同學抱著筆電哭著請我幫他修理時,裡面大剌剌開著 Foxy。


原因有幾個。


1. 很多人他沒有裝防毒軟體或是防火牆的觀念。
上面抓的東西,他也沒有安全概念,一拉回來點兩下就開了。


(1)沒裝防火牆而灌 foxy,別人很輕易的就知道有你這台電腦門戶洞開。
自然什麼啥阿貓阿狗的蠕蟲就會爬進來。


(2)沒裝防毒軟體而灌 foxy,其實很多人不知道,現在很多壓縮包和
exe 甚至連影片檔,都是有加料過的。也就是毒/木馬會被包裹在
上面,當你慾火焚身點下去的那一剎那,也是中標的時候 XD


2. 很多人不懂電腦,所以不懂 p2p 甚至 foxy 的原理,實質上會對硬體造成什麼損害。
foxy 就是採用 p2p 原理,只不過仔細去分析他的封包,就會發現他的抓檔手段很惡質。
我們都知道 p2p 原理就是把檔案切成一份一份,眾人各持有不同等份,透過 peer 交換機制,來達到各取所需的作用。機器會不斷的發出 request去問其他人有沒有缺的部分,有人有,再跟他抓回來。


(1) foxy 會抓檔那麼快的原因,就是因為他是以極暴力的手段,一次送幾十個連線去發出 request,幾近我們以前的”砍站行為”去“砍 peer”。


前面有人提到,分享器會掛掉,沒錯!!


林背還有遇過 switch 被 foxy 打掛的情形勒,這就是為什麼我那麼痛恨 foxy。整個實驗室幾十台 pc 用的網路,被一台 pc 上的 foxy打掛網路,你說幹不幹,別人都不用用網路了是不是。


暴力程度: foxy >>>>>>>> BitComet >>> emule。


為什麼這麼慘呢?


上面說過了, foxy 是幾乎以砍站行為去砍 peer。所以當你去抓人家檔時,你一次送出的並不是幾十個連線。因為你可能發現有 10 個人有這份檔案,所以你作的可能是發出幾百個 request。而你如果擁有數十份熱門 AV 檔呢? 哈哈,大家都來 request 你的電腦,如果你是直接一條網路線+一張網卡上網還好。你自己電腦 lag 到爆而已。但是你如果前面是接 hub / 分享器 / switch 呢,恭喜你,你即將成為被公幹的對象….


大家不但不用用網路了(因為塞到爆)。而且機器還可能被你的無知行為打爛。
其他的 p2p 軟體,現在都很好心的有作了限連線數甚至限流動作。
但是呢? foxy 沒有。然後這些愛用的人,又甚至連要裝限速軟體的常識都沒有。甚至他知道要裝,但是他只顧抓檔懶得裝。


遇到這種人,我第一句話就是問候他娘親。要是我室友,我就直接從幹網路設備上檔掉他的 mac address,要是他的電腦因此壞了,林背連他資料都懶得備,直接叫他重灌。


(2) 很多人不知道硬碟讀寫是怎樣運作的。
硬碟就是一個大圓盤。分區分格存你的資料。所以我們買來一顆硬碟要先幫他”格式化”(就是切成一格一格的拉),才能開始使用。


很多人常常誤以為,你存一個 100mb 的檔,假設 4mb 存一個格子的話,就是連續儲存在 25 格的位子上。錯了!!!! 如果你的硬碟不常重整的話。


你可能是存在非常零散間斷的 25 格上。as i said,他是一個大圓盤,所以這 25 格有可能是存在相差 180 度的位置上。所以當 p2p 軟體啟動時,很多人跟你要這個檔的第 2 格和第 4 格資料。你的硬碟就會一下讀第2格,一下讀第4格。偏偏這兩個差了180度的位置。想像一下我一次被要求發出500次對2和第4格的命令吧。幹,你硬碟連續這樣被濫操幾個月,不壞我頭給你拉。
所以這就是為什麼我賭爛很多女生用筆電抓的原因。


不備份、筆電硬碟修起來又困難、出事才在那裡靠背硬體很貴,資料很珍貴。
當初不要用 foxy 或多作一些功課不就沒事了 =_=


3. I/O 存取是很耗 CPU 資源的。在計算機系統裡,I/O 視為中斷,CPU 一秒鐘幾十萬上下,誰有空在那邊等你。老是被同學打來問,為什麼幫他新組的電腦打線上遊戲很慢,是不是我組裝功力有問題之類的。問到最後,才發現他是一邊掛p2p一邊打3d game,不會想用髒話幹爆他才怪。


4. request 也是很是佔網路頻寬的。很多人也認為,只有上下載行為才佔頻寬。錯了!!上下載行為會發出封包。發出 request 當然也會佔頻寬,尤其是 foxy 那種瘋狂發出封包的行為,更是佔頻寬之王。


偏偏一堆人不自覺。抓檔就算了,還不限流,不限流就算了,還灌 foxy。網路 8M/640k 他只出 1/8 的錢,卻要享有全部的頻寬權,被人拔線不檢討還在那邊嚷嚷他也有繳錢。這種人,我只有一句話,e04你娘!!!


抓 p2p 不是不可以。多作一點功課,少討一點厭。…看過不少同學就是因為這樣翻臉的。
–※ 發信站: 批踢踢兔(ptt2.cc)

2007年11月4日 星期日

[forward] How to Repair a Corrupt MBR and boot into Linux

How to Repair a Corrupt MBR and boot into Linux


There are times when you inadvertently overwrite your Master Boot Record. The end result being that you are unable to boot into Linux. This is especially true when you are dual booting between windows and Linux OSes. Once when I was working in Windows XP, I accidentally clicked the hibernate button instead of shutdown. And windows somehow overwrote my MBR which housed the GRUB boot loader. At such times, it pays to have this cool tip at hand.



This is what you do to restore the GRUB boot loader when faced with the above problem. First you need a Linux distribution CD. If you are using Fedora (RedHat) then the first CD is sufficient. But you may also use any of the live CDs like Knoppix, Ubuntu Live CD and so on.


With Fedora CD

Boot your computer with the first CD of Fedora in your CD drive (You have to enable your PC to boot from the cdrom, which you can set in the BIOS settings). At the installation boot prompt that you get, enter the following command:

boot: linux rescue

... and press Enter. The installer will ask you a few questions like the language you would like to use, the type of keyboard etc. Then, if you have linux previously installed on your machine, the Fedora installer will automatically detect it and mount it in the /mnt/sysimage directory. Once the linux partition is mounted, you are dropped into the command shell prompt. The next step is to make your newly mounted directory the root (or parent) directory. This you do by running the chroot command as follows:

# chroot /mnt/sysimage
# _

Now you are in the shell with respect to the parent directory which is the linux partition on your harddisk.



From here, the steps needed depends on which bootloader you are using. You have to have a fair idea what is the device node of your harddisk partition housing your MBR. In most cases, it is /dev/hda if you have an IDE harddisk. But if you have a SCSI harddisk, it will be /dev/sda.


Restoring GRUB
Execute the following command :

# grub-install /dev/hda

... to install GRUB boot loader on to your MBR. And then type exit to reboot the machine. Now your GRUB boot loader is fixed.


Restoring LILO

LILO stands for LInux LOader which was the boot loader used before GRUB was developed. It is fairly cryptic and is the default bootloader prior to and in RedHat 7.0 .

Here you just type the command :

# /sbin/lilo

... to install the bootloader on to the MBR.


If you don't have a Fedora CD, then you need not despair. You can also repair the boot loader using one of the numerous live CDs available.


Using Knoppix CD to repair the boot loader

Here you have to boot into knoppix (either GUI mode or text mode). Once you are logged in, fire up a terminal (in GUI mode) and type the following commands:

$ su -
# fdisk -l

This will list your hard disk partition information. From the listing, you can know in which partition you have linux installed. Now you have to mount the partition which contains the linux filesystem. For the sake of this discussion, let us assume it is /dev/hda3 .

# mount -t ext3 -o rw /dev/hda3 /mnt
#_

Now your linux partition is mounted at /mnt . Next you have to use the chroot command as follows:

# chroot /mnt
#_

The rest of the steps are the same as listed above for Restoring GRUB and LILO boot loaders.

Update (August 01 2007) : Many have said when they run the grub-install command after following the above steps, they get an error saying that /dev/hda is missing. The most probable reason is that when you chroot to the mount location, it does not have a copy of the device nodes on your machine. Here is a solution for that. If you have installed Linux with /boot, /usr and / in different partitions then the above method may not get the desired results and running the grub-install /dev/hda command after running chroot might give the error that there is no /dev/hda. This is because you have mounted only one of the partitions which houses '/' . And the error tells you that it cannot find the device nodes. In this scenario you can do the following :

Lets say I have Linux installed with / in /dev/hda2, /boot in /dev/hda1 with an ext3 filesystem. I boot using a Live CD as described above and then mount the partitions as follows :

# mount -t ext3 /dev/hda2 /mnt
# mount -t ext3 /dev/hda1 /mnt/boot

Remember that you are mounting the boot partition into the boot directory inside /mnt. Now mount the proc filesystem of your liveCD as follows (This is really an optional step):

# mount -t proc none /mnt/proc

Finally bind the device nodes build by your liveCD to the /mnt/dev location as follows :

# mount -o bind /dev /mnt/dev

Now you can chroot to the /mnt location and run the grub-install command as described above.

# chroot /mnt
# grub-install /dev/hda

Please note: This updated method is applicable only if you have a Linux installation spread across multiple partitions. If you have installed Linux in a single partition, the first and second step works flawlessly. At least it works for me.

2007年10月16日 星期二

grep的用法

語法 : grep [options] pattern 檔案

[options] 說明
-n 附帶列號
-i 不區分大小寫
-v 和pattern相反
-l 印出含有pattern之檔名
-c 只印出列號
-w 符合整個word,非部分符合
-r 遞迴遍歷目錄
-2 找到pattern那一列,並印出前後兩列,包含自已
-A 2 找到pattern那一列,並印出後兩列,包含自已
-B 2 找到pattern那一列,並印出前兩列,包含自已
-e 視pattern裡的所有character為一般的character
-x 除非pattern 符合 entire line , 否則不列印出來
-f 把patten放到檔案中

命令列程式

命令列程式
命令列程式通常是單獨存在的程式,執行前會先在搜尋路徑中去尋找。

常見的有:

cp, date, who, w, ls, cat, wc, last, mv, mkdir, rmdir, mv, ps, top, df, du, dd
ln, sort, sed, awk, ifconfig, dmesg, hostname, dnsdomainname, chmod, chown, chgrp
cut, grep, kill, more, less, mount, nice, ping, sleep, su, tar, gzip, touch,
uname, basename, dirname, tr, uniq, mail


以下介紹幾個簡單命令的用法

date
用途:顯示 or 設定 系統的日期和時間

用法:



date

結果顯示現在的日期時間

date MMDDhhmmYY

調整時間,格式為 月 MM 日 DD 時 hh 分 mm 年 YY

如: date 080109252002 是將時間調為 2002/08/01 09:25

date +格式

控制日期時間的輸出格式

如: date +'%d %H %M' 將顯示現在的 "日 時 分"

其它進一步的用法,請 man date 查閱線上文件。


who
用途:顯示現在誰登入主機

用法:

who

顯示: ols3 pts/0 Aug 1 13:54

whoami 則顯示自己的登入帳號

ls
用途:列出目錄內容

用法:



ls

結果:列出目前所在目錄的內容

ls -a

結果:列出目前所在目錄的內容,包括隱藏檔。

ls -la

結果:使用長列模式列出目前所在目錄的內容,包括隱藏檔。

其它進一步的用法,請 man ls 查閱線上文件。


cat
用途:連結檔案內容並顯示出來

用法:



cat dataf1

結果:顯示 dataf1 的檔案內容

cat dataf1 dataf2

結果:連結 dataf1, dataf1 的內容,並予顯示。

cat >>urmail.txt

kdkdkdkdkdkdkdkdkdk (Enter)

^D

將 cat 拿來當作簡易編輯器。

其它進一步的用法,請 man cat 查閱線上文件。


wc
用途:計算檔案內字數或列數

用法:



wc -l dataf1

結果:顯示 dataf1 的檔案內共有幾列

wc -c dataf1

結果:顯示 dataf1 共有多少字元。

wc -w dataf1

結果:顯示 dataf1 共有多少句元。

其它進一步的用法,請 man wc 查閱線上文件。


ln
用途:鏈結檔案;ln 提供一個方便的機制,使同一個檔案可以有多個檔名

用法:



ln f1 f2

結果:將 f1 鏈結到 f2 (硬式鏈結),f2 的檔案內容和 f1 一模一樣

ln -s f1 f3

結果:將 f1 鏈結到 f3 (軟式鏈結),f3 是 f1 的別名,取用 f3 時,實際上是存取 f1

ln -sf f1 f3

結果:同上,唯若 f3 早已存的話,將被刪除後再重建一個新的

其它進一步的用法,請 man ln 查閱線上文件。


basename
用途:取得路徑名稱中最後的檔名部份

用法:



basename /usr/local/bin/sftp

結果:出現 sftp

以下可以得到相同結果:

baseNAME.sh #! /bin/sh
# 模擬 basename 指令
bn=${1##*/}
echo $bn

===============
./baseNAME.sh /usr/local/bin/sftp
結果為
sftp



dirname
用途:取得路徑名稱中的目錄部份

用法:



dirname /usr/local/bin/sftp

結果:出現 /usr/local/bin

以下可以得到相同結果:

dirNAME.sh #! /bin/sh
# 模擬 dirname 指令
dn=${1%/*}
echo $dn

===============
./dirNAME.sh /usr/local/bin/sftp
結果為
/usr/local/bin



sort
用途:對文字檔的列做排序

用法:



sort dataf4

結果:將 dataf4 做升冪排序

sort -r dataf4

結果:將 dataf4 做降冪排序

sort -n dataf4

結果:將 dataf4 做升冪排序,但以字串的數值大小為比較的標準

sort -n +2 dataf3

結果:跳過前二欄,以 dataf3 中的第三欄做排序,且以字串的數值大小為比較的標準

sort -nr +2 -t: /etc/passwd

結果:-t: 是說改用 : 為分隔符號,+2 是說跳過前二欄,以 /etc/passwd 中的第三欄做降序排序,且 -n 指示 sort 以字串的數值大小為比較的標準,-r 是降冪排列

其它進一步的用法,請 man sort 查閱線上文件。


uniq
用途:對已排序好的檔案刪除重覆列

用法:



uniq dataf3

結果:若重覆列並未連續擺在一起, 則不會有任何作用

sort dataf3 | uniq

結果:刪除 dataf3 檔中的重覆列

sort dataf3 | uniq -d

結果:挑出重覆列

sort dataf3 | uniq -c

結果:計算每一列的重覆數目

其它進一步的用法,請 man uniq 查閱線上文件。


cut
用途:對檔案的每一列抽出某一部份

用法:



cut -c2 dataf1

結果:抽出 dataf1 中每一列的第 2 個字元

cut -c3-10 dataf1

結果:抽出 dataf1 中每一列的第 3 到第 10 個字元

cut -c9- dataf1

結果:抽出 dataf1 中每一列的第 9 以後的字元

cut -c1-3,22- dataf1

結果:抽出 dataf1 中每一列的第 1 到第 3 個字元、以及第 22 個以後的的字元

cut -d: -f1 /etc/passwd

結果:抽出 /etc/passwd 中的第一欄位,-d: 指示 cut 改用 : 為分隔符號,-f1 是第一欄之意

上述指令可拿來找出所有系統的帳號名稱

cut -d: -f3,4 /etc/passwd

結果:抽出 /etc/passwd 中的第3,4欄位

其它進一步的用法,請 man cut 查閱線上文件。


paste
用途:對檔案以列和列合併

用法:



paste dataf1 dataf2

結果:dataf1 的每一列 和 dataf2 的每一列合併,預設以 TAB 分隔

paste -d'#' dataf1 dataf2

結果:dataf1 的每一列 和 dataf2 的每一列合併,以 # 分隔

paste -s dataf4

結果:dataf4 的每一列自己合併在一起 (-s : same file),預設以 TAB 分隔

其它進一步的用法,請 man paste 查閱線上文件。


tr
用途:轉換或刪除字元

用法:



tr k K < dataf1

結果:dataf1 的 k 換成 K 字元

tr ',' '\n' < ttt

結果:ttt 的 , 號換成 換行字元(\n)

tr -d k

結果:k 字元全刪除

cut -d: -f1-6 /etc/passwd | tr : '+'

結果:將 passwd 的六個欄改以 + 分隔

tr '[A-Z]' '[a-z]' < dataf1

結果:將大寫全換成小寫字母

tr '[a-z]' '[A-Z]' < dataf1

結果:將小寫全換成大寫字母

tr -s ' ' ' ' < dataf1

結果:將多餘的空白移除只剩一個 (-s 是壓擠的意思)

其它進一步的用法,請 man tr 查閱線上文件。


grep
用途:顯示符合樣式的列

用法:



grep A *

結果:將含有 A 這個字元的檔案及列顯示出來

grep -i A *

結果:將含有 A或a 這個字元的檔案及列顯示出來 (-i 是不分大小寫之意)

grep -v La data3

結果:將不含 La 的列顯示出來 (-v 是不包含之意)

grep -l La *

結果:只顯示那些檔案包含 La,不秀出符合的列

grep -n La *

結果:也秀出列號

dmesg | grep eth0

結果:將含有 eth0 的訊息列顯示出來

grep -q keyword filename

結果:若 filename 含有 keyword 則傳回 0 (真),否則傳為非 0

命令執行完之後,它的傳回值放在 $? 這個變數中,只要 echo $? 便可得知成功與否,請記住:0 為成功,非 0 為失敗 !


練習用的資料檔
dataf1 的內容:

John TNC 721 7654321
Marry TCC 678 1234567
Jack KCC 123 ABCDEFG
Bob PTC 345 efghijk
Anne TPC 987 1098643


dataf2 的內容:

Susan XXX 121 1AB57RT
Jeff AAA 478 JaBdkdk
Henry BBB 193 LaLaLaL
Allan DDD 621 Bobojto
Ken JJJ 094 sssssss


dataf3 的內容:

987 XXX 121 1AB57RT
234 AAA 478 JaBdkdk
765 BBB 193 LaLaLaL
512 DDD 621 Bobojto
363 JJJ 094 sssssss
765 BBB 193 LaLaLaL


dataf4的內容:

98
2341
7
51
363


常用的特殊字元
\b 後退
\f 跳頁
\n 換行字元
\r return
\t TAB


一個命令列執行好幾個命令
有二種方式:


每個命令之間用 ; 號隔開

如 ./configure ; make ; make install

每個命令之間用 && 號隔開

如 ./configure && make && make install

問題:這二者有何差別?

&& 表示前一個命令執行成功之後,才會接著執行下一個,這樣可讓我們確保所有的命令是否都成功執行。

這經常運用在自動安裝 script 檔中,以下是我平時使用的自動安裝 Apache 及 PHP 的 script 檔:

#! /bin/sh

tar xvzf apache*.gz &&
tar xvzf php*.gz &&


echo "Configure apache ...." &&
cd apache* &&
./configure --prefix=/usr/local/apache &&
cd .. &&
cd php* &&
./configure \
--with-apache=../apache_1.3.26 \
--with-mysql=/home/mysql &&
make &&
make install &&
cd .. &&

cd apache* &&
./configure \
--prefix=/usr/local/apache \
--activate-module=src/modules/php4/libphp4.a &&
make &&
make install &&

cd ../php* &&
cp -f php.ini-dist /usr/local/lib/php.ini



註: 若一列寫不完,可在該列末尾加上接續符號 \

註: 另有 || 的用法:如 命令1 || 命令2 || 命令3

|| 是或之意,當命令1執行成功時,就不會再往下執行,若命令1執行失敗,才會執行命命2

只有當前面二個命命都執行失敗,命令3 才會被執行

也可以把數個命令弄成一組,然後整組去執行它:

第一種方法:(命令1; 命令2; 命令3; ....)

( ) 會開啟一個子 shell 環境來執行括號中的命令組

以下是把一組命令放入背景中執行:

(sort mydata -o result.txt; procdata result.txt) &

第二種方法:{ 命令1; 命令2; 命令3; .... }

不同的是,此法是把這些命令組在現行的 shell 中執行,而非在子 shell 中執行

注意 { 右方、} 左方都要有空白,每個命令都要以 ';'這個符號結束

命令列郵寄帶檔的方法
以下是將 README 這個檔案郵件帶檔寄給 ols3@www.tnc.edu.tw

#! /bin/sh

# 由命令列寄帶檔的信件

# 方法 1: 使用 uuencode 編碼

例1
uuencode README README | mail -s "test attach msg file" ols3@www.tnc.edu.tw

上述的意思是說:把 README 這個檔案(第一個 README)予以 uuencode 編碼,且將 README (第二個 README) 這個名字寫入編碼檔的檔頭,再交給 mail 寄給收信者。

例2
uuencode nc11nt.zip nc11nt.zip | mail -s "test attach msg file" ols3@www.tnc.edu.tw

# 解碼法: uudecode 編碼檔
# 或由 OutLook Express 等讀取信件的程式自動解碼。

# ------------------------------------------------------------------------------

# 方法 2: 使用 base64 編碼

uuencode -m README README | mail -s "test attach msg file" ols3@www.tnc.edu.tw

# 解碼:
# uudecode 編碼檔
# 或
# uudecode 編碼檔 -o 指定輸出檔名
# 如 uudecode encode.txt -o nc11.zip

WinZip 也可以對 uuencode 編碼檔加以解碼,方法如下:
1. 把 uuencode 檔存為 .uue,若是 base64 編碼可存成 .b64
2. 用 WinZip 開啟編碼檔,即可按一般解壓動作來予以解碼。

=========================================================

# 註: uuencode 的用法例:

uuencode nc11nt.zip nc11nt.zip > p.txt

第一個檔名 nc11nt.zip 告訴 uuencode 要編碼的檔案是那一個,
第二個檔名 nc11nt.zip 是要 uuencode 把該檔名寫入 p.txt 表頭
它會在 p.txt 的第一列出現:
begin 600 nc11nt.zip

這樣子別人收到您的編碼檔,對方才知道您編碼之前的檔案格式為何?
因此,一般而言,uuencode 之後的二個檔名,我們都會弄成一樣。

p.txt 的內容截錄如下:

begin 600 nc11nt.zip
M4$L#!!0``@`(`.B88QW[!E;'=`<``)T2```(````9V5T;W!T+FC%5]MNXS@2
M?8X!_T-A%IAM[#B77LS+-B*T)9'%JE.G3I5.CNBSS"MAA5=&.UH82TOIS=I_Z':(J&_63U8M
M2T\'_4,Z_?3/3QE]^HCK%-<9KI]P_94NK90T,0O_**RD2U/K(AC,:*!S6.IV
MIJ6"=55)PO]K83V9!?E2TM7PEOITK>96V*-@Q'TV93
MM\.[^E3%'1F5YE$^2(NM4[QXOK52#]*1TG2R+$Z6NC[!KN3.SLE\RH*C<"F*
M5"DY6%>WAC">ABQ-CNYV5*=3BB9\@7)S)?N'LE=L.K3%_);6T
MHJ*;>EZI'(]SJ9TDX;J=-3]RI2QH_A3VO87F.4F%]Y80KL,]G:63NIUD+R/D
M[T!X]MT2LHA5AW#XB2KA-QO?AF`3:<&PL3>E62.N$D81Z:.J*II+JIUM[6`I?1M,OXQNI]0;WM&WWGC<&T[OSK'4EP9OD9QH2*W6E8)=1&6%]D\AF5\O
MQOTOV-#[>7`]F-ZQ_Y>#Z?!B,J'+T9AZ=-,;3P?]V^O>F&YNQS>CR04R/9&R
M09AC?Q=BIO3*`,A">J$J%X*_0VX=W*L**L6#1(YS":X4)"@'Y;^?P19R$I71
MRQ#M2SZ?DTN>!NKW1S=W@^'5A^O!S\QTA*^-S^C1*C#+FW>3'TLIH[__XV_T
......省略
M`@`(`%9^1B0K8B6N!%\``%3Q```*``````````$`(`"V@50,`0!H;V)B:70N
M='AT4$L!`A0`%``"``@`H8Y&),B0K1B*"P``D@&L!`')E861M92YT>'102P4&``````D`"0#I`0``,G`
end

==============================================================

用以下方法即可解碼回來:

uudecode p.txt -o nc11.zip

[精華] Grep 用法

Grep : g (globally) search for a re (regular expression ) and p (print ) the results.

1、參數:
-I :忽略大小寫
-c :列印匹配的行數
-l :從多個檔中查找包含匹配項
-v :查找不包含匹配項的行
-n:列印包含匹配項的行和行標

2、RE(正則運算式)
\ 忽略正則運算式中特殊字元的原有含義
^ 匹配正則運算式的開始行
$ 匹配正則運算式的結束行
\< 從匹配正則運算式的行開始
\>; 到匹配正則運算式的行結束
[ ] 單個字元;如[A] 即A符合要求
[ - ] 範圍 ;如[A-Z]即A,B,C一直到Z都符合要求
. 所有的單個字元
* 所有字元,長度可以為0

3、舉例
# ps -ef | grep in.telnetd
root 19955 181 0 13:43:53 ? 0:00 in.telnetd

# more size.txt size檔的內容
b124230
b034325
a081016
m7187998
m7282064
a022021
a061048
m9324822
b103303
a013386
b044525
m8987131
B081016
M45678
B103303
BADc2345

# more size.txt | grep '[a-b]' 範圍 ;如[A-Z]即A,B,C一直到Z都符合要求
b124230
b034325
a081016
a022021
a061048
b103303
a013386
b044525
# more size.txt | grep '[a-b]'*
b124230
b034325
a081016
m7187998
m7282064
a022021
a061048
m9324822
b103303
a013386
b044525
m8987131
B081016
M45678
B103303
BADc2345

# more size.txt | grep '' 單個字元;如[A] 即A符合要求
b124230
b034325
b103303
b044525
# more size.txt | grep '[bB]'
b124230
b034325
b103303
b044525
B081016
B103303
BADc2345

# grep 'root' /etc/group
root::0:root
bin::2:root,bin,daemon
sys::3:root,bin,sys,adm
adm::4:root,adm,daemon
uucp::5:root,uucp
mail::6:root
tty::7:root,tty,adm
lp::8:root,lp,adm
nuucp::9:root,nuucp
daemon::12:root,daemon

# grep '^root' /etc/group 匹配正則運算式的開始行
root::0:root


# grep 'uucp' /etc/group
uucp::5:root,uucp
nuucp::9:root,nuucp

# grep '\uucp::5:root,uucp


# grep 'root$' /etc/group 匹配正則運算式的結束行
root::0:root
mail::6:root


# more size.txt | grep -i 'b1..*3' -i :忽略大小寫

b124230
b103303
B103303

# more size.txt | grep -iv 'b1..*3' -v :查找不包含匹配項的行

b034325
a081016
m7187998
m7282064
a022021
a061048
m9324822
a013386
b044525
m8987131
B081016
M45678
BADc2345

# more size.txt | grep -in 'b1..*3'
1:b124230
9:b103303
15:B103303

# grep '$' /etc/init.d/nfs.server | wc -l
128
# grep '\$' /etc/init.d/nfs.server | wc –l 忽略正則運算式中特殊字元的原有含義

15
# grep '\$' /etc/init.d/nfs.server
case "$1" in
>;/tmp/sharetab.$$
[ "x$fstype" != xnfs ] && \
echo "$path\t$res\t$fstype\t$opts\t$desc" \
>;>;/tmp/sharetab.$$
/usr/bin/touch -r /etc/dfs/sharetab /tmp/sharetab.$$
/usr/bin/mv -f /tmp/sharetab.$$ /etc/dfs/sharetab
if [ -f /etc/dfs/dfstab ] && /usr/bin/egrep -v '^[ ]*(#|$)' \
if [ $startnfsd -eq 0 -a -f /etc/rmmount.conf ] && \
if [ $startnfsd -ne 0 ]; then
elif [ ! -n "$_INIT_RUN_LEVEL" ]; then
while [ $wtime -gt 0 ]; do
wtime=`expr $wtime - 1`
if [ $wtime -eq 0 ]; then
echo "Usage: $0 { start | stop }"


# more size.txt

the test file
their are files
The end

# grep 'the' size.txt
the test file
their are files

# grep '\the test file
their are files

# grep 'the\>;' size.txt
the test file

# grep '\;' size.txt
the test file

# grep '\<[Tt]he\>;' size.txt
the test file
The end

2007年9月4日 星期二

轉貼-嵌入式設備上的 Linux 系統開發

嵌入式設備上的 Linux 系統開發
級別: 初級
Anand K Santhanam (mailto:asanthan@in.ibm.com?subject=嵌入式設備上的 Linux 系統開發&cc=asanthan@in.ibm.com), 軟體工程師, IBM Global Services
Vishal Kulkarni (mailto:kvishal@in.ibm.com?subject=嵌入式設備上的 Linux 系統開發&cc=kvishal@in.ibm.com), 軟體工程師, IBM Global Services

2002 年 3 月 01 日
如果您剛接觸嵌入式開發,那麼大量可用的引導裝載程式(bootloader)、規模縮小的分發版(distribution)、檔系統和 GUI 看起來可能太多了。但是這些豐富的選項實際上是一種恩賜,允許您調整開發或用戶環境以完全符合您的需要。對 Linux 嵌入式開發的概述將幫助您理解所有這些選項。
Linux 正在嵌入式開發領域穩步發展。因為 Linux 使用 GPL(請參閱本文後面的 參考資料),所以任何對將 Linux 定制於 PDA、掌上機或者可佩帶設備感興趣的人都可以從網際網路免費下載其內核和應用程式,並開始移植或開發。許多 Linux 改良品種迎合了嵌入式/即時市場。它們包括 RTLinux(即時 Linux)、uclinux(用於非 MMU 設備的 Linux)、Montavista Linux(用於 ARM、MIPS、PPC 的 Linux 分發版)、ARM-Linux(ARM 上的 Linux)和其他 Linux 系統(請參閱 參考資料以鏈結到本文中提到的這些和其他術語及產品。)
嵌入式 Linux 開發大致涉及三個層次:引導裝載程式、Linux 內核和圖形用戶介面(或稱 GUI)。在本文中,我們將集中討論涉及這三層的一些基本概念;深入瞭解引導裝載程式、內核和檔系統是如何交互的;並將研究可用於檔系統、GUI 和引導裝載程式的眾多選項中的一部分。
引導裝載程式
引導裝載程式通常是在任何硬體上執行的第一段代碼。在象臺式機這樣的常規系統中,通常將引導裝載程式裝入主引導記錄(Master Boot Record,(MBR))中,或者裝入 Linux 駐留的磁片的第一個磁區中。通常,在臺式機或其他系統上,BIOS 將控制移交給引導裝載程式。這就提出了一個有趣的問題:誰將引導裝載程式裝入(在大多數情況中)沒有 BIOS 的嵌入式設備上呢?
解決這個問題有兩種常規技術:專用軟體和微小的引導代碼(tiny bootcode)。
專用軟體可以直接與遠端系統上的快閃記憶體設備進行交互並將引導裝載程式安裝在快閃記憶體的給定位置中。 快閃記憶體設備是與存儲設備功能類似的特殊晶片,而且它們能持久存儲資訊 ― 即,在重新引導時不會擦除其內容。
這個軟體使用目標(在嵌入式開發中,嵌入式設備通常被稱為 目標)上的 JTAG 埠,它是用於執行外部輸入(通常來自主機機器)的指令的介面。JFlash-linux 是一種用於直接寫快閃記憶體的流行工具。它支援為數眾多的快閃記憶體晶片;它在主機機器(通常是 i386 機器 ― 本文中我們把一台 i386 機器稱為 主機)上執行並通過 JTAG 介面使用平行埠訪問目標的快閃記憶體晶片。當然,這意味著目標需要有一個平行介面使它能與主機通信。Jflash-linux 在 Linux 和 Windows 版本中都可使用,可以在命令行中用以下命令啟動它:
Jflash-linux

某些種類的嵌入式設備具有 微小的引導代碼― 根據幾個位元組的指令 ― 它將初始化一些 DRAM 設置並啟用目標上的一個串列(或者 USB,或者乙太網)埠與主機程式通信。然後,主機程式或裝入程式可以使用這個連接將引導裝載程式傳送到目標上,並將它寫入快閃記憶體。
在安裝它並給予其控制後,這個引導裝載程式執行下列各類功能:
• 初始化 CPU 速度
• 初始化記憶體,包括啟用記憶體庫、初始化記憶體配置寄存器等
• 初始化序列埠(如果在目標上有的話)
• 啟用指令/資料快取記憶體
• 設置堆疊指標
• 設置參數區域並構造參數結構和標記(這是重要的一步,因為內核在標識根設備、頁面大小、記憶體大小以及更多內容時要使用引導參數)
• 執行 POST(加電自檢)來標識存在的設備並報告任何問題
• 為電源管理提供掛起/恢復支援
• 跳轉到內核的開始
帶有引導裝載程式、參數結構、內核和檔系統的系統典型記憶體佈局可能如下所示:

清單 1. 典型記憶體佈局
/* Top Of Memory */
Bootloader
Parameter Area
Kernel
Filesystem
/* End Of Memory */

嵌入式設備上一些流行的並可免費使用的 Linux 引導裝載程式有 Blob、Redboot 和 Bootldr(請參閱 參考資料獲得鏈結)。所有這些引導裝載程式都用於基於 ARM 設備上的 Linux,並需要 Jflash-linux 工具用於安裝。
一旦將引導裝載程式安裝到目標的快閃記憶體中,它就會執行我們上面提到的所有初始化工作。然後,它準備接收來自主機的內核和檔系統。一旦裝入了內核,引導裝載程式就將控制轉給內核。


設置工具鏈
設置工具鏈在主機機器上創建一個用於編譯將在目標上運行的內核和應用程式的構建環境 ― 這是因為目標硬體可能沒有與主機相容的二進位執行級別。
工具鏈由一套用於編譯、彙編和鏈結內核及應用程式的元件組成。 這些組件包括:
• Binutils ― 用於操作二進位檔的實用程式集合。它們包括諸如 ar 、 as 、 objdump 、 objcopy 這樣的實用程式。
• Gcc― GNU C 編譯器。
• Glibc― 所有用戶應用程式都將鏈結到的 C 庫。避免使用任何 C 庫函數的內核和其他應用程式可以在沒有該庫的情況下進行編譯。
構建工具鏈建立了一個交叉編譯器環境。 本地編譯器編譯與本機同類的處理器的指令。 交叉編譯器運行在某一種處理器上,卻可以編譯另一種處理器的指令。重頭設置交叉編譯器工具鏈可不是一項簡單的任務:它包括下載源代碼、修補補丁、配置、編譯、設置頭檔、安裝以及很多很多的操作。另外,這樣一個徹底的構建過程對記憶體和硬碟的需求是巨大的。如果沒有足夠的記憶體和硬碟空間,那麼在構建階段由於相關性、配置或頭檔設置等問題會突然冒出許多問題。
因此能夠從網際網路上獲得已預編譯的二進位檔是一件好事(但不太好的一點是,目前它們大多數只限於基於 ARM 的系統,但遲早會改變的)。一些比較流行的已預編譯的工具鏈包括那些來自 Compaq(Familiar Linux )、LART(LART Linux)和 Embedian(基於 Debian 但與它無關)的工具鏈 ― 所有這些工具鏈都用於基於 ARM 的平臺。
內核設置
Linux 社區正積極地為新硬體添加功能部件和支援、在內核中修正錯誤並且及時地進行常規改進。這導致大約每 6 個月(或 6 個月不到)就有一個穩定的 Linux 樹的新發行版。不同的維護者維護針對特定體系結構的不同內核樹和補丁。當為一個專案選擇了一個內核時,您需要評估最新發行版的穩定性如何、它是否符合專案要求和硬體平臺、從編程角度來看它的舒適程度以及其他難以確定的方面。還有一點也非常重要:找到需要應用於基本內核的所有補丁,以便為特定的體系結構調整內核。
內核佈局
內核佈局分為特定於體系結構的部分和與體系結構無關的部分。內核中特定於體系結構的部分首先執行,設置硬體寄存器、配置記憶體映射、執行特定於體系結構的初始化,然後將控制轉給內核中與體系結構無關的部分。系統的其餘部分在這第二個階段期間進行初始化。內核樹下的目錄 arch/ 由不同的子目錄組成,每個子目錄用於一個不同的體系結構(MIPS、ARM、i386、SPARC、PPC 等)。每一個這樣的子目錄都包含 kernel/ 和 mm/ 子目錄,它們包含特定於體系結構的代碼來完成象初始化記憶體、設置 IRQ、啟用快取記憶體、設置內核頁面表等操作。一旦裝入內核並給予其控制,就首先調用這些函數,然後初始化系統的其餘部分。
根據可用的系統資源和引導裝載程式的功能,內核可以編譯成 vmlinux、Image 或 zImage。vmlinux 和 zImage 之間的主要區別在於 vmlinux是實際的(未壓縮的)可執行檔,而 zImage是或多或少包含相同資訊的自解壓壓縮檔 ― 只是壓縮它以處理(通常是 Intel 強制的)640 KB 引導時間的限制。有關所有這些的權威性解釋,請參閱 Linux Magazine的文章“Kernel Configuration: dealing with the unexpected”(請參閱 參考資料)。
內核鏈結和裝入
一旦為目標系統編譯了內核後,通過使用引導裝載程式(它已經被裝入到目標的快閃記憶體中),內核就被裝入到目標系統的記憶體(在 DRAM 中或者在快閃記憶體中)。通過使用串列、USB 或乙太網埠,引導裝載程式與主機通信以將內核傳送到目標的快閃記憶體或 DRAM 中。在將內核完全裝入目標後,引導裝載程式將控制傳遞給裝入內核的位址。
內核可執行檔由許多鏈結在一起的物件檔組成。物件檔有許多節,如文本、資料、init 資料、bass 等等。這些物件檔都是由一個稱為 鏈結器腳本的檔鏈結並裝入的。這個鏈結器腳本的功能是將輸入物件檔的各節映射到輸出檔中;換句話說,它將所有輸入物件檔都鏈結到單一的可執行檔中,將該可執行檔的各節裝入到指定位址處。 vmlinux.lds是存在於 arch// 目錄中的內核鏈結器腳本,它負責鏈結內核的各個節並將它們裝入記憶體中特定偏移量處。典型的 vmlinux.lds 看起來象這樣:

清單 2. 典型的 vmlinux.lds 文件
OUTPUT_ARCH() /* includes architecture type */
ENTRY(stext) /* stext is the kernel entry point */
SECTIONS /* SECTIONS command describes the layout
of the output file */
{
. = TEXTADDR; /* TEXTADDR is LMA for the kernel */
.init : { /* Init code and data*/
_stext = .; /* First section is stext followed
by __init data section */
__init_begin = .;
*(.text.init)
__init_end = .;
}
.text : { /* Real text segment follows __init_data section */
_text = .;
*(.text)
_etext = .; /* End of text section*/
}
.data :{
_data=.; /* Data section comes after text section */
*(.data)
_edata=.;
} /* Data section ends here */
.bss : { /* BSS section follows symbol table section */
__bss_start = .;
*(.bss)
_end = . ; /* BSS section ends here */
}
}

LMA 是裝入模組位址;它表示將要裝入內核的目標虛擬記憶體中的位址。 TEXTADDR 是內核的虛擬起始位址,並且在 arch// 下的 Makefile 中指定它的值。這個位址必須與引導裝載程式使用的位址相匹配。
一旦引導裝載程式將內核複製到快閃記憶體或 DRAM 中,內核就被重新定位到 TEXTADDR — 它通常在 DRAM 中。然後,引導裝載程式將控制轉給這個位址,以便內核能開始執行。
參數傳遞和內核引導
stext 是內核入口點,這意味著在內核引導時將首先執行這一節下的代碼。它通常用組合語言編寫,並且通常它在 arch// 內核目錄下。這個代碼設置內核頁面目錄、創建身份內核映射、標識體系結構和處理器以及執行分支 start_kernel (初始化系統的主常式)。
start_kernel 調用 setup_arch 作為執行的第一步,在其中完成特定於體系結構的設置。這包括初始化硬體寄存器、標識根設備和系統中可用的 DRAM 和快閃記憶體的數量、指定系統中可用頁面的數目、檔系統大小等等。所有這些資訊都以參數形式從引導裝載程式傳遞到內核。
將參數從引導裝載程式傳遞到內核有兩種方法:parameter_structure 和標記列表。在這兩種方法中,不贊成使用參數結構,因為它強加了限制:指定在記憶體中,每個參數必須位於 param_struct 中的特定偏移量處。最新的內核期望參數作為標記列表的格式來傳遞,並將參數轉化為已標記格式。 param_struct 定義在 include/asm/setup.h 中。它的一些重要欄位是:

清單 3. 樣本參數結構
struct param_struct {
unsigned long page_size; /* 0: Size of the page */
unsigned long nr_pages; /* 4: Number of pages in the system */
unsigned long ramdisk /* 8: ramdisk size */
unsigned long rootdev; /* 16: Number representing the root device */
unsigned long initrd_start; /* 64: starting address of initial ramdisk */
/* This can be either in flash/dram */
unsigned long initrd_size; /* 68: size of initial ramdisk */
}

請注意:這些數表示定義欄位的參數結構中的偏移量。這意味著如果引導裝載程式將參數結構放置在位址 0xc0000100,那麼 rootdev 參數將放置在 0xc0000100 + 16,initrd_start 將放置在 0xc0000100 + 64 等等 ― 否則,內核將在解釋正確的參數時遇到困難。
正如上面提到的,因為從引導裝載程式到內核的參數傳遞會有一些約束條件,所以大多數 2.4.x 系列內核期望參數以已標記的列表格式傳遞。在已標記的列表中,每個標記由標識被傳遞參數的 tag_header 以及其後的參數值組成。標記列表中標記的常規格式可以如下所示:

清單 4. 樣本標記格式。內核通過 頭來標識每個標記。
#define
struct {
u32 ;
u32 ;
};
/* Example tag for passing memory information */
#define ATAG_MEM 0x54410002 /* Magic number */
struct tag_mem32 {
u32 size; /* size of memory */
u32 start; /* physical start address of memory*/
};

setup_arch 還需要對快閃記憶體存儲庫、系統寄存器和其他特定設備執行記憶體映射。一旦完成了特定於體系結構的設置,控制就返回到初始化系統其餘部分的 start_kernel 函數。這些附加的初始化任務包含:
• 設置陷阱
• 初始化中斷
• 初始化計時器
• 初始化控制臺
• 調用 mem_init ,它計算各種區域、高記憶體區等內的頁面數量
• 初始化 slab 分配器並為 VFS、緩衝區快取記憶體等創建 slab 快取記憶體
• 建立各種檔系統,如 proc、ext2 和 JFFS2
• 創建 kernel_thread ,它執行檔系統中的 init 命令並顯示 lign 提示符。 如果在 /bin、/sbin 或 /etc 中沒有 init 程式,那麼內核將執行檔系統的 /bin 中的 shell。






回頁首



設備驅動程式
嵌入式系統通常有許多設備用於與用戶交互,象觸摸屏、小鍵盤、滾動輪、感測器、RA232 介面、LCD 等等。除了這些設備外,還有許多其他專用設備,包括快閃記憶體、USB、GSM 等。內核通過所有這些設備各自的設備驅動程式來控制它們,包括 GUI 用戶應用程式也通過訪問這些驅動程式來訪問設備。本節著重討論通常幾乎在每個嵌入式環境中都會使用的一些重要設備的設備驅動程式。
幀緩衝區驅動程式
這是最重要的驅動程式之一,因為通過這個驅動程式才能使系統螢幕顯示內容。幀緩衝區驅動程式通常有三層。最底層是基本控制臺驅動程式 drivers/char/console.c,它提供了文本控制臺常規介面的一部分。通過使用控制臺驅動程式函數,我們能將文本列印到螢幕上 ― 但圖形或動畫還不能(這樣做需要使用視頻模式功能,通常出現在中間層,也就是 drivers/video/fbcon.c 中)。這個第二層驅動程式提供了視頻模式中繪圖的常規介面。
幀緩衝區是顯卡上的記憶體,需要將它記憶體映射到用戶空間以便可以將圖形和文本能寫到這個記憶體段上:然後這個資訊將反映到螢幕上。幀緩衝區支援提高了繪圖的速度和整體性能。這也是頂層驅動程式引人注意之處:頂層是非常特定於硬體的驅動程式,它需要支援顯卡不同的硬體方面 ― 象啟用/禁用顯卡控制器、深度和模式的支援以及調色板等。所有這三層都相互依賴以實現正確的視頻功能。與幀緩衝區有關的設備是 /dev/fb0(主設備號 29,次設備號 0)。
輸入設備驅動程式
可觸摸板是用於嵌入式設備的最基本的用戶交互設備之一 ― 小鍵盤、感測器和滾動輪也包含在許多不同設備中以用於不同的用途。
觸摸板設備的主要功能是隨時報告用戶的觸摸,並標識觸摸的座標。這通常在每次發生觸摸時,通過生成一個中斷來實現。
然後,這個設備驅動程式的角色是每當出現中斷時就查詢觸摸屏控制器,並請求控制器發送觸摸的座標。一旦驅動程式接收到座標,它就將有關觸摸和任何可用資料的信號發送給用戶應用程式,並將資料發送給應用程式(如果可能的話)。然後用戶應用程式根據它的需要處理資料。
幾乎所有輸入設備 ― 包括小鍵盤 ― 都以類似原理工作。
快閃記憶體 MTD 驅動程式
MTD 設備是象快閃記憶體晶片、小型快閃記憶體卡、記憶棒等之類的設備,它們在嵌入式設備中的使用正在不斷增長。
MTD 驅動程式是在 Linux 下專門為嵌入式環境開發的新的一類驅動程式。相對於常規塊設備驅動程式,使用 MTD 驅動程式的主要優點在於 MTD 驅動程式是專門為基於快閃記憶體的設備所設計的,所以它們通常有更好的支援、更好的管理和基於磁區的擦除和讀寫操作的更好的介面。Linux 下的 MTD 驅動程式介面被劃分為兩類模組:用戶模組和硬體模組。
用戶模組
這些模組提供從用戶空間直接使用的介面:原始字元訪問、原始塊訪問、FTL(快閃記憶體轉換層,Flash Transition Layer ― 用在快閃記憶體上的一種檔系統)和 JFS(即日誌檔系統,Journaled File System ― 在快閃記憶體上直接提供檔系統而不是類比塊設備)。用於快閃記憶體的 JFS 的當前版本是 JFFS2(稍後將在本文中描述)。
硬體模組
這些模組提供對記憶體設備的物理訪問,但並不直接使用它們。通過上述的用戶模組來訪問它們。這些模組提供了在快閃記憶體上讀、擦除和寫操作的實際常式。
MTD 驅動程式設置
為了訪問特定的快閃記憶體設備並將檔系統置於其上,需要將 MTD 子系統編譯到內核中。這包括選擇適當的 MTD 硬體和用戶模組。當前,MTD 子系統支援為數眾多的快閃記憶體設備 ― 並且有越來越多的驅動程式正被添加進來以用於不同的快閃記憶體晶片。
有兩個流行的用戶模組可啟用對快閃記憶體的訪問: MTD_CHAR 和 MTD_BLOCK 。
MTD_CHAR 提供對快閃記憶體的原始字元訪問,而 MTD_BLOCK 將快閃記憶體設計為可以在上面創建檔系統的常規塊設備(象 IDE 磁片)。與 MTD_CHAR 關聯的設備是 /dev/mtd0、mtd1、mtd2(等等),而與 MTD_BLOCK 關聯的設備是 /dev/mtdblock0、mtdblock1(等等)。由於 MTD_BLOCK 設備提供象塊設備那樣的類比,通常更可取的是在這個模擬基礎上創建象 FTL 和 JFFS2 那樣的檔系統。
為了進行這個操作,可能需要創建分區表將快閃記憶體設備分拆到引導裝載程式節、內核節和檔系統節中。樣本分區表可能包含以下資訊:

清單 5. MTD 的簡單快閃記憶體設備分區
struct mtd_partition sample_partition = {
{
/* First partition */
name : bootloader, /* Bootloader section */
size : 0x00010000, /* Size */
offset : 0, /* Offset from start of flash- location 0x0*/
mask_flags : MTD_WRITEABLE /* This partition is not writable */
},
{ /* Second partition */
name : Kernel, /* Kernel section */
size : 0x00100000, /* Size */
offset : MTDPART_OFS_APPEND, /* Append after bootloader section */
mask_flags : MTD_WRITEABLE /* This partition is not writable */
},
{ /* Third partition */
name : JFFS2, /* JFFS2 filesystem */
size : MTDPART_SIZ_FULL, /* Occupy rest of flash */
offset : MTDPART_OFS_APPEND /* Append after kernel section */
}
}

上面的分區表使用了 MTD_BLOCK 介面對快閃記憶體設備進行分區。這些分區的設備節點是:

簡單快閃記憶體分區的設備節點
User device node Major number Minor number
Bootloader /dev/mtdblock0 31 0
Kernel /dev/mtdblock1 31 1
Filesystem /dev/mtdblock2 31 2

在本例中,引導裝載程式必須將有關 root 設備節點(/dev/mtdblock2)和可以在快閃記憶體中找到檔系統的位址(本例中是 FLASH_BASE_ADDRESS + 0x04000000 )的正確參數傳遞到內核。一旦完成分區,快閃記憶體設備就準備裝入或掛裝檔系統。
Linux 中 MTD 子系統的主要目標是在系統的硬體驅動程式和上層,或用戶模組之間提供通用介面。硬體驅動程式不需要知道象 JFFS2 和 FTL 那樣的用戶模組使用的方法。所有它們真正需要提供的就是一組對底層快閃記憶體系統進行 read 、 write 和 erase 操作的簡單常式。






回頁首



嵌入式設備的檔系統
系統需要一種以結構化格式存儲和檢索資訊的方法;這就需要檔系統的參與。Ramdisk(請參閱 參考資料)是通過將電腦的 RAM 用作設備來創建和掛裝檔系統的一種機制,它通常用於無盤系統(當然包括微型嵌入式設備,它只包含作為永久存儲媒質的快閃記憶體晶片)。
用戶可以根據可靠性、健壯性和/或增強的功能的需求來選擇檔系統的類型。下一節將討論幾個可用選項及其優缺點。
第二版擴展檔系統(Ext2fs)
Ext2fs 是 Linux 事實上的標準檔系統,它已經取代了它的前任 ― 擴展檔系統(或 Extfs)。Extfs 支持的檔大小最大為 2 GB,支持的最大檔案名稱大小為 255 個字元 ― 而且它不支援索引節點(包括資料修改時間標記)。Ext2fs 做得更好;它的 優點是:
• Ext2fs 支援達 4 TB 的記憶體。
• Ext2fs 檔案名稱最長可以到 1012 個字元。
• 當創建檔系統時,管理員可以選擇邏輯塊的大小(通常大小可選擇 1024、2048 和 4096 位元組)。
• Ext2fs 了實現快速符號鏈結:不需要為此目的而分配資料塊,並且將目標名稱直接存儲在索引節點(inode)表中。這使性能有所提高,特別是在速度上。
因為 Ext2 檔系統的穩定性、可靠性和健壯性,所以幾乎在所有基於 Linux 的系統(包括臺式機、伺服器和工作站 ― 並且甚至一些嵌入式設備)上都使用 Ext2 檔系統。然而,當在嵌入式設備中使用 Ext2fs 時,它有一些 缺點:
• Ext2fs 是為象 IDE 設備那樣的塊設備設計的,這些設備的邏輯塊大小是 512 位元組,1 K 位元組等這樣的倍數。這不太適合於磁區大小因設備不同而不同的快閃記憶體設備。
• Ext2 檔系統沒有提供對基於磁區的擦除/寫操作的良好管理。在 Ext2fs 中,為了在一個磁區中擦除單個位元組,必須將整個磁區複製到 RAM,然後擦除,然後重寫入。考慮到快閃記憶體設備具有有限的擦除壽命(大約能進行 100,000 次擦除),在此之後就不能使用它們,所以這不是一個特別好的方法。
• 在出現電源故障時,Ext2fs 不是防崩潰的。
• Ext2 檔系統不支援損耗平衡,因此縮短了磁區/快閃記憶體的壽命。(損耗平衡確保將位址範圍的不同區域輪流用於寫和/或擦除操作以延長快閃記憶體設備的壽命。)
• Ext2fs 沒有特別完美的磁區管理,這使設計塊驅動程式十分困難。
由於這些原因,通常相對於 Ext2fs,在嵌入式環境中使用 MTD/JFFS2 組合是更好的選擇。
用 Ramdisk 掛裝 Ext2fs
通過使用 Ramdisk 的概念,可以在嵌入式設備中創建並掛裝 Ext2 檔系統(以及用於這一目的的任何檔系統)。

清單 6. 創建一個簡單的基於 Ext2fs 的 Ramdisk
mke2fs -vm0 /dev/ram 4096
mount -t ext2 /dev/ram /mnt
cd /mnt
cp /bin, /sbin, /etc, /dev ... files in mnt
cd ../
umount /mnt
dd if=/dev/ram bs=1k count=4096 of=ext2ramdisk

mke2fs 是用於在任何設備上創建 ext2 檔系統的實用程式 — 它創建超級塊、索引節點以及索引節點表等等。
在上面的用法中, /dev/ram 是上面構建有 4096 個塊的 ext2 檔系統的設備。然後,將這個設備( /dev/ram )掛裝在名為 /mnt 的臨時目錄上並且複製所有必需的檔。一旦複製完這些檔,就卸裝這個檔系統並且設備( /dev/ram )的內容被轉儲到一個檔(ext2ramdisk)中,它就是所需的 Ramdisk(Ext2 檔系統)。
上面的順序創建了一個 4 MB 的 Ramdisk,並用必需的檔實用程式來填充它。
一些要包含在 Ramdisk 中的重要目錄是:
• /bin ― 保存大多數象 init 、 busybox 、 shell 、檔管理實用程式等二進位檔。
• /dev― 包含用在設備中的所有設備節點
• /etc― 包含系統的所有配置檔
• /lib― 包含所有必需的庫,如 libc、libdl 等
日誌快閃記憶體檔系統,版本 2(JFFS2)
瑞典的 Axis Communications 開發了最初的 JFFS,Red Hat 的 David Woodhouse 對它進行了改進。 第二個版本,JFFS2,作為用於微型嵌入式設備的原始快閃記憶體晶片的實際檔系統而出現。JFFS2 檔系統是日誌結構化的,這意味著它基本上是一長列節點。每個節點包含有關檔的部分資訊 ― 可能是檔的名稱、也許是一些資料。相對於 Ext2fs,JFFS2 因為有以下這些 優點而在無盤嵌入式設備中越來越受歡迎:
• JFFS2 在磁區級別上執行快閃記憶體擦除/寫/讀操作要比 Ext2 檔系統好。
• JFFS2 提供了比 Ext2fs 更好的崩潰/掉電安全保護。當需要更改少量資料時,Ext2 檔系統將整個磁區複製到記憶體(DRAM)中,在記憶體中合併新資料,並寫回整個磁區。這意味著為了更改單個字,必須對整個磁區(64 KB)執行讀/擦除/寫常式 ― 這樣做的效率非常低。要是運氣差,當正在 DRAM 中合併資料時,發生了電源故障或其他事故,那麼將丟失整個資料集合,因為在將資料讀入 DRAM 後就擦除了快閃記憶體磁區。JFFS2 附加檔而不是重寫整個磁區,並且具有崩潰/掉電安全保護這一功能。
• 這可能是最重要的一點:JFFS2 是專門為象快閃記憶體晶片那樣的嵌入式設備創建的,所以它的整個設計提供了更好的快閃記憶體管理。
因為本文主要是寫關於快閃記憶體設備的使用,所以在嵌入式環境中使用 JFFS2 的 缺點很少:
• 當檔系統已滿或接近滿時,JFFS2 會大大放慢運行速度。這是因為垃圾收集的問題(更多資訊,請參閱 參考資料)。
創建 JFFS2 檔系統
在 Linux 下,用 mkfs.jffs2 命令創建 JFFS2 檔系統(基本上是使用 JFFS2 的 Ramdisk)。

清單 7. 創建 JFFS2 檔系統
mkdir jffsfile
cd jffsfile
/* copy all the /bin, /etc, /usr/bin, /sbin/ binaries and /dev entries
that are needed for the filesystem here */
/* Type the following command under jffsfile directory to create the JFFS2 Image */
./mkfs.jffs2 -e 0x40000 -p -o ../jffs.image

上面顯示了 mkfs.jffs2 的典型用法。 -e 選項確定快閃記憶體的擦除磁區大小(通常是 64 千位元組)。 -p 選項用來在映射的剩餘空間用零填充。 -o 選項用於輸出檔,通常是 JFFS2 檔系統映射 ― 在本例中是 jffs.image。一旦創建了 JFFS2 檔系統,它就被裝入快閃記憶體中適當的位置(引導裝載程式告知內核查找檔系統的位址)以便內核能掛裝它。
tmpfs
當 Linux 運行於嵌入式設備上時,該設備就成為功能齊全的單元,許多守護進程會在後臺運行並生成許多日誌消息。另外,所有內核日誌記錄機制,象 syslogd、dmesg 和 klogd,會在 /var 和 /tmp 目錄下生成許多消息。由於這些進程產生了大量資料,所以允許將所有這些寫操作都發生在快閃記憶體是不可取的。由於在重新引導時這些消息不需要持久存儲,所以這個問題的解決方案是使用 tmpfs。
tmpfs 是基於記憶體的檔系統,它主要用於減少對系統的不必要的快閃記憶體寫操作這一唯一目的。因為 tmpfs 駐留在 RAM 中,所以寫/讀/擦除的操作發生在 RAM 中而不是在快閃記憶體中。因此,日誌消息寫入 RAM 而不是快閃記憶體中,在重新引導時不會保留它們。tmpfs 還使用磁片交換空間來存儲,並且當為存儲檔而請求頁面時,使用虛擬記憶體(VM)子系統。
tmpfs 的 優點包括:
• 動態檔系統大小 ― 檔系統大小可以根據被複製、創建或刪除的檔或目錄的數量來縮放。使得能夠最理想地使用記憶體。
• 速度 ― 因為 tmpfs 駐留在 RAM,所以讀和寫幾乎都是暫態的。即使以交換的形式存儲檔,I/O 操作的速度仍非常快。
tmpfs 的一個 缺點是當系統重新引導時會丟失所有資料。因此,重要的資料不能存儲在 tmpfs 上。
掛裝 tmpfs
諸如 Ext2fs 和 JFFS2 等大多數其他檔系統都駐留在底層塊設備之上,而 tmpfs 與它們不同,它直接位於 VM 上。因而,掛裝 tmpfs 檔系統是很簡單的事:

清單 8. 掛裝 tmpfs
/* Entries in /etc/rc.d/rc.sysinit for creating/using tmpfs */
# mount -t tmpfs tmpfs /var -o size=512k
# mkdir -p /var/tmp
# mkdir -p /var/log
# ln -s /var/tmp /tmp

上面的命令將在 /var 上創建 tmpfs 並將 tmpfs 的最大大小限制為 512 K。同時,tmp/ 和 log/ 目錄成為 tmpfs 的一部分以便在 RAM 中存儲日誌消息。
如果您想將 tmpfs 的一個項添加到 /etc/fstab,那麼它可能看起來象這樣:
tmpfs /var tmpfs size=32m 0 0

這將在 /var 上掛裝一個新的 tmpfs 檔系統。


圖形用戶介面(GUI)選項
從用戶的觀點來看,圖形用戶介面(GUI)是系統的一個最至關重要的方面:用戶通過 GUI 與系統進行交互。所以 GUI 應該易於使用並且非常可靠。但它還需要是有記憶體意識的,以便在記憶體受限的、微型嵌入式設備上可以無縫執行。所以,它應該是羽量級的,並且能夠快速裝入。
另一個要考慮的重要方面涉及許可證問題。一些 GUI 分發版具有允許免費使用的許可證,甚至在一些商業產品中也是如此。另一些許可證要求如果想將 GUI 合併入項目中則要支付版稅。
最後,大多數開發人員可能會選擇 XFree86,因為 XFree86 為他們提供了一個能使用他們喜歡的工具的熟悉環境。但是市場上較新的 GUI,象 Century Software 的 Microwindows(Nano-X)和 Trolltech 的 QT/Embedded,與 X 在嵌入式 Linux 的競技舞臺中展開了激烈競爭,這主要是因為它們佔用很少的資源、執行的速度很快並且具有定制視窗構件的支援。
讓我們看一看這些選項中的每一個。
Xfree86 4.X(帶幀緩衝區支持的 X11R6.4)
XFree86 Project, Inc. 是一家生產 XFree86 的公司,該產品是一個可以免費重複分發、開放源碼的 X Window 系統。X Window 系統(X11)為應用程式以圖形方式進行顯示提供了資源,並且它是 UNIX 和類 UNIX 的機器上最常用的視窗系統。它很小但很有效,它運行在為數眾多的硬體上,它對網路透明並且有良好的文檔說明。X11 為視窗管理、事件處理、同步和客戶機間通信提供強大的功能 ― 並且大多數開發人員已經熟悉了它的 API。它具有對內核幀緩衝區的內置支持,並佔用非常少的資源 ― 這非常有助於記憶體相對較少的設備。X 伺服器支援 VGA 和非 VGA 圖形卡,它對顏色深度 1、2、4、8、16 和 32 提供支援,並對渲染提供內置支援。最新的發行版是 XFree86 4.1.0。
它的 優點包括:
• 幀緩衝區體系結構的使用提高了性能。
• 佔用的資源相對很小 ― 大小在 600 K 到 700 K 位元組的範圍內,這使它很容易在小型設備上運行。
• 非常好的支持:線上有許多文檔可用,還有許多專用於 XFree86 開發的郵遞列表。
• X API 非常適合擴展。
它的 缺點包括:
• 比最近出現的嵌入式 GUI 工具性能差。
• 此外,當與 GUI 中最新的開發 ― 象專門為嵌入式環境設計的 Nano-X 或 QT/Embedded ― 相比時,XFree86 似乎需要更多的記憶體。
Microwindows
Microwindows 是 Century Software 的開放源代碼項目,設計用於帶小型顯示單元的微型設備。它有許多針對現代圖形視窗環境的功能部件。象 X 一樣,有多種平臺支持 Microwindows。
Microwindows 體系結構是基於客戶機/伺服器的並且具有分層設計。最底層是螢幕和輸入設備驅動程式(關於鍵盤或滑鼠)來與實際硬體交互。在中間層,可移植的圖形引擎提供對線的繪製、區域的填充、多邊形、裁剪以及顏色模型的支援。
在最上層,Microwindows 支援兩種 API:Win32/WinCE API 實現,稱為 Microwindows;另一種 API 與 GDK 非常相似,它稱為 Nano-X。Nano-X 用在 Linux 上。它是象 X 的 API,用於佔用資源少的應用程式。
Microwindows 支援 1、2、4 和 8 bpp(每圖元的位元數)的 palletized 顯示,以及 8、16、24 和 32 bpp 的真彩色顯示。Microwindows 還支援使它速度更快的幀緩衝區。Nano-X 伺服器佔用的資源大約在 100 K 到 150 K 位元組。
原始 Nano-X 應用程式的平均大小在 30 K 到 60 K。由於 Nano-X 是為有記憶體限制的低端設備設計的,所以它不象 X 那樣支援很多函數,因此它實際上不能作為微型 X(Xfree86 4.1)的替代品。
可以在 Microwindows 上運行 FLNX,它是針對 Nano-X 而不是 X 進行修改的 FLTK(快速輕巧工具箱(Fast Light Toolkit))應用程式開發環境的一個版本。本文中描述 FLTK。
Nano-X 的 優點包括:
• 與 Xlib 實現不同,Nano-X 仍在每個客戶機上同步運行,這意味著一旦發送了客戶機請求包,伺服器在為另一個客戶機提供服務之前一直等待,直到整個包都到達為止。這使伺服器代碼非常簡單,而運行的速度仍非常快。
• 佔用很小的資源
Nano-X 的 缺點包括:
• 聯網功能部件至今沒有經過適當地調整(特別是網路透明性)。
• 還沒有太多現成的應用程式可用。
• 與 X 相比,Nano-X 雖然近來正在加速開發,但仍沒有那麼多文檔說明而且沒有很好的支持,但這種情形會有所改變。
Microwindows 上的 FLTK API
FLTK 是一個簡單但靈活的 GUI 工具箱,它在 Linux 世界中贏得越來越多的關注,它特別適用于佔用資源很少的環境。它提供了您期望從 GUI 工具箱中獲得的大多數視窗構件,如按鈕、對話方塊、文本框以及出色的“賦值器”選擇(用於輸入數值的視窗構件)。還包括滑動器、捲軸、刻度盤和其他一些構件。
針對 Microwindows GUI 引擎的 FLTK 的 Linux 版本被稱為 FLNX。FLNX 由兩個組件構成:Fl_Widget 和 FLUID。Fl_Widget 由所有基本視窗構件 API 組成。FLUID(快速輕巧的用戶介面設計器(Fast Light User Interface Designer, FLUID))是用來產生 FLTK 源代碼的圖形編輯器。總的來說,FLNX 是能用來為嵌入式環境創建應用程式的一個出色的 UI 構建器。
Fl_Widget 佔用的資源大約是 40 K 到 48 K,而 FLUID(包括了每個窗口構件)大約佔用 380 K。這些非常小的資源佔用率使 Fl_Widget 和 FLUID 在嵌入式開發世界中非常受歡迎。
優點包括:
• 習慣於在象 Windows 這樣已建立得較好的環境中開發基於 GUI 的應用程式的任何人都會非常容易地適應 FLTK 環境。
• 它的文檔包括一本十分完整且編寫良好的手冊。
• 它使用 LGPL 進行分發,所以開發人員可以靈活地發放他們應用程式的許可證。
• FLTK 是一個 C++ 庫(Perl 和 Python 綁定也可用)。面向物件模型的選擇是一個好的選擇,因為大多數現代 GUI 環境都是面向物件的;這也使將編寫的應用程式移植到類似的 API 中變得更容易。
• Century Software 的環境提供了幾個有用的工具,諸如 ScreenToP 和 ViewML 流覽器。
它的 缺點是:
• 普通的 FLTK 可以與 X 和 Windows API 一同工作,而 FLNX 不能。它與 X 的不相容性阻礙了它在許多項目中的使用。
Qt/Embedded
Qt/Embedded 是 Trolltech 新開發的用於嵌入式 Linux 的圖形用戶介面系統。Trolltech 最初創建 Qt 作為跨平臺的開發工具用於 Linux 臺式機。它支援各種有 UNIX 特點的系統以及 Microsoft Windows。KDE ― 最流行的 Linux 桌面環境之一,就是用 Qt 編寫的。
Qt/Embedded 以原始 Qt 為基礎,並做了許多出色的調整以適用於嵌入式環境。Qt Embedded 通過 Qt API 與 Linux I/O 設施直接交互。那些熟悉並已適應了面向物件編程的人員將發現它是一個理想環境。而且,面向物件的體系結構使代碼結構化、可重用並且運行快速。與其他 GUI 相比,Qt GUI 非常快,並且它沒有分層,這使得 Qt/Embedded 成為用於運行基於 Qt 的程式的最緊湊環境。
Trolltech 還推出了 Qt 掌上機環境(Qt Palmtop Environment,俗稱 Qpe)。Qpe 提供了一個基本桌面視窗,並且該環境為開發提供了一個易於使用的介面。Qpe 包含全套的個人資訊管理(Personal Information Management (PIM))應用程式、網際網路客戶機、實用程式等等。然而,為了將 Qt/Embedded 或 Qpe 集成到一個產品中,需要從 Trolltech 獲得商業許可證。(原始 Qt 自版本 2.2 以後就可以根據 GPL 獲得 。)
它的 優點包括:
• 面向物件的體系結構有助於更快地執行
• 佔用很少的資源,大約 800 K
• 抗鋸齒文本和混合視頻的象素映射
它的 缺點是:
• Qt/Embedded 和 Qpe 只能在獲得商業許可證的情況下才能使用。






回頁首



結束語
嵌入式 Linux 開發正迅速地發展著。您必須學習並從引導裝載程式和分發版到檔系統和 GUI 中的每一個事物的各種選項中作出選擇。但是要感謝有這種選擇自由度以及非常活躍的 Linux 社區,Linux 上的嵌入式開發已經達到了新的境界,並且調整模組以適合您的規範從未比現在更簡單。這已經導致出現了許多時新的手持和微型設備作為開放盒,這是件好事 ― 因為事實是您不必成為一個專家從這些模組中進行選擇來調整您的設備以滿足您自己的要求和需要。
我們希望這篇對嵌入式 Linux 領域的介紹性概述能激起您進行試驗的欲望,並且希望您將體會擺弄微型設備的樂趣以滿足您的愛好。為進一步有助於您的專案,請參閱下面的“參考資料”,鏈結到有關我們這裏已經概述的技術的更深入的資訊。

參考資料
引導:
• 您可以參閱本文在 developerWorks 全球站點上的 英文原文.
• 如需獲得對 vmlinux 和 zimage 之間區別的極好解釋,請在 Alessandro Rubini 編寫的“ Kernel Configuration: dealing with the unexpected( Linux Magazine)的一文中找到“Booting your kernel”一節。
小型分發版:
• The Embedded Linux Distributions Quick Reference Guide涵蓋了許多商業的和開放源碼的分發版( Linux Devices,2001 年 8 月)。

• 請查看另一個 詳盡的分發版和有用的工具的清單( Linux-embedded.com)。
工具鏈:
• Wiki 工具鏈頁面包含到本文提到的所有三個工具鏈的鏈結,還有對它們的評論。
設備驅動程式:
• Memory Technology Device (MTD) Subsystem for Linux的目的是簡化記憶體設備(特別是快閃記憶體設備)的驅動程式的創建。

• Vipin Malik 編寫的 The Linux MTD, JFFS HOWTO將幫助您使 MTD 和 JFFS2 一起工作。

• Linux for PowerPC Embedded Systems HOWTO有一個很好的設備驅動程式清單。

• 理解 Linux device drivers有助於理解本篇介紹性文章( Penguin Magazine)。

• 要精通 Linux 設備驅動程式,請閱讀 O'Reilly 的 Linux Device Drivers,第 2 版一書。
有用的工具:
• Binutils、 GCC和 Glibc都可從 Free Software Foundation 下載獲得。

• 許多有用的下載都可從 Netwinder.org獲得,這是一個致力於 NetWinder 平臺上開發工作的志願者站點。

• 請在 Mark Nielsen 寫得非常棒的 How to use a Ramdisk for Linux一文中閱讀有關 Ramdisk 的所有資訊。

• FLNX 是以 FLTK(快速輕巧的工具箱)為基礎的。
檔系統:
• 第二版擴展檔系統 Ext2fs的主頁在 SourceForge。

• Red Hat 英國公司的 David Woodhouse 概述了大量有關 JFFS2:日誌快閃記憶體檔系統,第 2 版的背景知識。

• 您可以在 Linux HeadQuarters 閱讀更多有關 tmpfs的信息。

• Cliff Brake 和 Jeff Sutherland 編寫的 Flash Filesystems for Embedded Linux Systems一文論述了用於快閃記憶體設備的更多檔系統( Embedded Linux Journal)。
GUI:
• Xfree86 是 X 開發的主頁。

• 請查看一篇對 Microwindows 的一些缺點(GNOME gtk 開發人員的郵遞列表)的討論(時間比較長了)。

• 在 Trolltech 上查找有關 Qt/Embedded的更多資訊。

• The Embedded Linux GUI/Windowing Quick Reference Guide中有豐富的鏈結( Linux Devices,2002 年 2 月)。
一般參考資料:
• General Public License 或 GPL確保用戶複製、分發和修改軟體的權利。

• ARM Linux是您瞭解有關 Linux 用於 ARM 處理器的資訊的一個非常好的站點。它由 ARM 的創建者 Russell King 來維護。

• Penguinppc.org是關於 Linux 用於 PowerPC 系列處理器的的主頁。該站點上有一個關於為基於 PPC 的體系結構建立工具鏈的資料豐富的教程。

• Linux Devices是一個非常全面的站點,它包含有關 Linux 和嵌入式開發的出版發行、快速參考、新聞和特色報告等各種資訊。

• Silicon Penguin列表站點上擁有嵌入式 Linux 參考資料的詳盡集合。

• ARMLinux - the book可從 Aleph One 上獲得。您可以定購一本,也可以 線上閱讀。

• 嵌入式 Linux 協會(Embedded Linux Consortium)是一個非贏利的互助協會,它歡迎致力於嵌入式 Linux 領域的開發人員成為會員。

• IBM 的 Linux wristwatch是運行 Linux 的微型嵌入式設備的示例;本文的作者之一,Vishal Kulkarni 也參與了它的研發。請在 本文( FreeOS.com,2001 年 3 月)中閱讀有關它的資訊。

• 在 developerWorks上流覽 更多 Linux 參考資料。

• 在 developerWorks上流覽 更多無線領域的參考資料。

作者簡介

Anand K Santhanam 在印度 Madras 大學獲得電腦科學工學學士學位。自 1999 年 7 月以來他一直在印度為 IBM Global Services(軟體實驗室)工作。他是 IBM Linux 小組的成員,這個小組主要致力於嵌入式系統中的 ARM-Linux、設備驅動程式和電源管理的研究和開發。他感興趣的其他領域是 O/S 本質和聯網。可以通過 mailto:asanthan@in.ibm.com?cc=asanthan@in.ibm.com 與他聯繫。

Vishal Kulkarni 從印度 Maharashtra 的 Shivaji 大學獲得電子工程的學士學位。自 1999 年 3 月以來他一直在印度為 IBM Global Services(軟體實驗室)工作。在此之前,他曾在美國 IBM Austin 工作了一年半多。他是 IBM Linux 小組的成員,這個小組主要致力於嵌入式設備上的 ARM-Linux、設備驅動程式和 GUI。他感興趣的其他領域是 O/S 本質和聯網。可以通過 mailto:kvishal@in.ibm.com?cc=kvishal@in.ibm.com與他聯繫。