Email me: jollen # jollen.org

more: Jollen 的 Embedded Linux 教育訓練

« May 2006 | (回到Blog入口) | October 2006 »

September 2006 歸檔

September 16, 2006

PowerPC 衝吧!

這星期四五都在把玩公司的 PowerPC 板子,目標是 build BIOS (U-Boot)、kernel (2.6) 與基本的 root filesystem。因此就來把這二天建立 root filesystem 的心得簡單整理一下與大家分享。

PowerPC 是定義在 large-scale 的嵌入式系統,因此與一般的 small-scale embedded system 有幾個技術面的差異,若以 embedded Linux 的角度來看,幾點主要差異是:

(1) large-scale ES 通常都有 mass storage (eg. HD) 或利用 NFS/BOOTP/PXE 來開機後由 NFS server mount 完整系統,所以開機時只要先提供 NFS root filesystem 即可。
(2) 由 (1),因此可以「灌」完整的 Linux distribution 在「NFS server」上,以 PowerPC 來講的話,可以選擇 Yellow Dog Linux、Red Hat Linux for PowerPC 與 Debian PPC (或 Ubuntu PPC);Jollen 的話是選擇用 Debian PPC。
(3) NFS root filesystem 可以用 busybox,不過建議是 porting 完整的 init 與 mount,因此需要下載 sysvinit 與 util-linux 二個套件。
(4) 要 mount NFS 的話,target 端最好要有 portmap daemon,以加速 NFS mount,也才不會出現「portmap: NFS server local not responding」之類的訊息。(建議是一定要裝啦)

其它該注意的小地方也給大家分享一下:

(1) 網路上可以教到 NFS mount 的做法有二種,一種是傳遞 "nfsroot" 參數給 kernel,由 kernel 去 mount,另一種是 build 一個 "NFS root filesystem",然後用 fstab (也就是 mount) 去做,不過 Jollen 的建議是後者。有一些網路的文件也是建議後者。
(2) portmap 需要 tcp_wrapper 套件,記得一併下載。
(3) IP 的設定建議在開機時由 kernel 去做,不要開完機後再用 ifconfig 去設定。

提供這二天建的 NFS root filesystem for PowerPC 給大家參考,檔案要由 forum 下載。基本上,使用下列套件來 build root filesystem 就能做出一個簡單的 NFS rootfs 了 (這是 Jollen 使用的套件版本):

* busybox 1.1.3 (關掉內建的 mount / unmount)
* util-linux 2.12r
* tcp_wrapper 7.6 (for NFS mount)
* portmap_4 (for NFS mount)

我們的板子採用 U-Boot 來做開機程式。記得要在 U-Boot 下設定 kernel command line,把 NFS 的設定加上去才行。以下 Jollen 設定 kernel 的開機參數('ip='用來做Kernel Mode IP Configuration):

u-boot> set bootargs console=ttyS0,115200 root=/dev/ram0 ramdisk=8192 netconsole=6665@10.100.10.12/eth0,6666@10.100.10.20/
ip=10.100.10.12:10.100.10.20:10.100.10.254:255.0.0.0:ppc:eth0

'netconsole=' 的話可有可無,加上去的話可以配合 netcat 來看到 "console" 畫面。這是我們的 PowerPC 板子用的開機指令:

u-boot> tftp 1000000 uImage; tftp 1200000 urootfs_ppc.img; bootm 1000000 1200000

開機後進入 Linux 命令模式後,再用 mount 把 NFS server 的目錄 mount 即可,由於我們用的 kernel 是 2.6,因此是用 'switch_root' 指令來變更 root 目錄,而不是用 "chroot"。

September 18, 2006

U-Boot 的網路卡驅動程式架構

PowerPC 再衝吧!整理一下這次 porting PowerPC 網路卡 driver 的重點。今天先就架構面的重點做整理。

要了解以下內容,您至少要對以下主題有基本的認知:

(1) U-Boot 如何使用 CONFIG_* 定義 driver,要把 networking 相關的 driver 打開。
(2) U-Boot 的開機與 Board-Level 初始化流程
(3) U-Boot 的 BSP 架構實作方法 (extern)

(Jollen 的 U-Boot 學員可參考講義 Lecture 3 & Lecture 4)

Jollen 的任務是將 vendor 提供的 DST 整合至 U-Boot,以支援我們 PowerPC 板子上的 PHY (Broadcom 的 Gigalan)。

net/eth.c:eth_initialize()

這是重要的 Networking 初始化的核心層,在這裡加入

int eth_initialize(bd_t *bis)
{
    char enetvar[32], env_enetaddr[6];
    int i, eth_number = 0;
    char *tmp, *end;
    eth_devices = NULL;
    eth_current = NULL;

#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)
    miiphy_init();
#endif
    ...
#ifdef CONFIG_DB64360
    mv6436x_eth_initialize(bis);
#endif
    ...
#if defined(CONFIG_PPC750GIGE)
    ppc750_eth_initialize(bis);
#endif

    ...
}

在這裡可以看到很多 driver 的定義 (CONFIG_*),我們在最後加上自己板子的 driver 定義。ppc750_eth_initialize() 是 BSP code,所以必須實作到 board 的目錄裡面。然後在 board/xxx/實作 PHY 的 driver,因為是 BSP code,依架 U-Boot 的習慣,我們必須把 PHY 的 driver 放在 board 目錄下。

實作 ppc750_eth_initialize()

接下來的重要工作,當然就是實作 ppc750_eth_initialize(),U-Boot 在開機時,會呼叫我們 PHY driver 的進入點,而這個進入點函數就叫 ppc750_eth_initialize(),U-Boot 底下的網路卡 driver 基本架構大致雷同。以下的程式碼就是我們板子的 PHY driver 進入點:

int ppc750_eth_initialize(bd_t *bis) // called from eth.c:eth_initialize()
{
    struct eth_device *dev[MAX_NUM_ETH_PORTS]; // ethernet device 的結構
    int i;

    printf("Initializing ethernet ports!\n");

    for (i = 0; i < MAX_NUM_ETH_PORTS; i++)
    {
        if (dev[i] == NULL) {
        dev[i] = (struct eth_device *)malloc(sizeof(struct eth_device));
    }

         /* 這裡是最重要的啦,要填寫 init, halt, send, recv 四個動作 (operation) 的實作函數,大家可以看一下 struct eth_device 的原型
        */
        dev[i]->init = ppc750_ether_init; // 下達網路命令時,會先呼叫 init。
        dev[i]->halt = ppc750_stop_ethernet; // 把網路關閉時回呼的。
        dev[i]->send = ppc750_send_packet; //網路命令要送出封包時回呼的。
        dev[i]->recv = ppc750_poll; // 要接收封包時回呼的。

        eth_register(dev[i]); // 註冊 ethernet device 到 U-Boot 核心層
    }

    return i;
}

到這裡是 U-Boot 提供給網路卡 driver 的架構,接著當然就是要實作 init, halt, send, recv 這四個 operation 了!底層 Driver 的 operation 是跟硬體相關的,也就是看 datasheet 寫 driver 的工作!

September 19, 2006

嵌入式Linux的Web Application Framework

今天在survey與初步build所謂的"a web application framework in an embedded Linux system",這是8月份在LinuxDevices.com的一篇文章介紹的題目。Web-application或者是"Application Web化"是近幾年來非常明顯的一個趨勢,思考 Embedded System 的 Web Application (Embedded Web Applications ?) 是一個頗為有趣的主題,也有許多的 paper 在討論這個題目。

目前嵌入式Linux上的web application與desktop (PC) 的web application並無太大差異,許多文件也是只以"embedded web server"做為核心的出發點,這篇在linuxdevices.com上看到的文章也是。不過這篇文章倒值得對這個題目有興趣的朋友一讀。

作者開場白就點出了這個題目的主軸:

As devices are increasingly more networked, an embedded web server is becoming a standard way for users to interact with and configure an embedded device using a standard web browser.

對於web application in an embedded linux system的研究範疇,就 Jollen 目前的認知來講,可以分成幾個層級來探討:

(1) 低階做法:設計一個 "monolithic" 應用程式來處理 HTTP 並輸出 HTML,例如在 Jollen 的 "Embedded Linux 嵌入式系統原理與實務 ,3e" 書上給的 web.c (a dirty embedded web server) 範例。
(2) 中階做法:建構 embedded web server 的 root filesystem,例如加入 thttpd 的使用,如此一來便能透過 CGI 規範來設計 web application;thttpd 的 CGI 大多以 C 語言撰寫。
(3) 高階做法:建構 "framework" 來設計與實作 web application,linuxdevices.com 上的這篇文章就是在討論這種做法。

實作上,要建構 "web appication framework" 的基礎平臺 (aka root filesystem),能選擇的 open source 解決方案其實很多 (各種排列組合);不過 Jollen 把此文作者建議的 "components" for web appication framework 實際 build 後,發現還真的不賴說,大家可以試試!以下是該作者建議的 solution:

1. Web Server: Cherokee (1MiB)
2. Model: SQLite (290KB)
3. View: Clearsilver (170KB)
4. Controller: Python (2-3MB)

看到 Model/View/Controller 了!這就是 "framework" 的重點-以MVC模式設計與實作web applications!


Figure-source (引用自): linuxdevices.com, http://www.linuxdevices.com/articles/AT5550934609.html.

這個Cherokee也是一個open source的embedded web server,試用後覺得還不賴,可以列入 thttpd/boa外的其它選擇。Cherokee還真的挺強大的,讚讚讚,列入10月份Jollen-Kit! Builder Training Edition的更新roadmap,與所有學員分享!

節錄 Cherokee 的介紹:

Cherokee is a very fast, flexible and easy to configure Web Server. It supports the widespread technologies nowadays: FastCGI, SCGI, PHP, CGI, TLS and SSL encrypted connections, Virtual hosts, Authentication, on the fly encoding, Apache compatible log files, and much more.

目前 Jollen 把基本的環境 build 好了,10月份的Jollen-Kit! Builder Training Edition也會加入,目前則是還在拼湊demo架構 (應用程式) 中。因為 Python 初學中,程式寫的哩哩辣辣的 (why not PHP >_<")。

* "Must enable us to implement a clean MVC type architecture," I think this is good.
* "Must support a high level language like python for rapid development," Good but I'd like to think more.

September 20, 2006

一篇有關 Reentrant Code Program (可重覆進入程式碼) 的文章

"Reentrant Code" 是 embedded system 相關教科書很重要的一個主題,學習 Linux 驅動程式的學員也一定了解到這個主題的重要性。

由於 Linux 驅動程式裡的每一個 "operation" (eg. fops->read) 是 "共用" 的,例如 major number 相同的 device file (minor number 不同) 是共用同一塊 code,所以必須考量程式碼的「可重覆進入」寫法 (thinking about filp->private data)。

這也是為什麼在 Jollen 的 Linux 驅動程式課程裡,我們如此這般在強調 Reentrant Code (Reentrant Function) 這個主題,也花了許多時間介紹 Linux 驅動程式的 "reentrant" 觀念。

Linux 驅動程式有許多主題是一點點搞不懂,就會全盤皆不懂的,reentrant code 的觀念是其中之一。由於許多學員對於 reentrant code 的理論不甚了解,因此建議未來要來上課的同學可以事先研讀這篇寫的相當好的文章:

http://www.unet.univie.ac.at/aix/aixprggd/genprogc/writing_reentrant_thread_safe_code.htm

在 Jollen 多年的 Linux 驅動程式授課經驗中,reentrant code 是同學比較不容易搞清楚的觀念,可是卻也是一開始我們課程就會講到的主題;我們提到當上層 callback 下層的驅動程式時,什麼條件下下層必考慮可重覆進入的問題。要學好 Linux 驅動程式,建議無論如何也要搞懂這個主題!

September 21, 2006

利用 Monotone 與朋友客戶協同發展與測試

Monotone 是一個版本控管系統,但是他跟 SVN/CVS 並無衝突,我們由 monotone 首頁節錄官方的摘要說明如下:

monotone is a free distributed version control system. it provides a simple, single-file transactional version store, with fully disconnected operation and an efficient peer-to-peer synchronization protocol.

SVN 是廣為使用的版本控管系統,並將取代 CVS。然而 SVN/CVS 的操作與管理的學習成本是挺高的,我們無法「勸導」客戶積極地配合我們的 CVS 模式來跟我們的程式碼同步,還好 monotone 可以代替原本 CVS 的角色 (版本控制),並提供更簡便的版本控管機制給「朋友」或「客戶」。

Monotone 將所有不同版本的程式碼建成「一個資料庫」,附檔名是 *.mtn,比如我把 Jollen-Kit! Builder 利用 monotone 成立一個專案 (project) 並建立 jkbuilder.mtn 資料庫,那麼我只要把 jkbuilder.mtn 遞交給朋友,我朋友就可以利用 monotone 把 jkbuilder.mtn 裡的程式碼 "check out" 出來。

Monotone 用在教育訓練也是很適合的,我們現在把一大堆課程的東西都「打包」成 *.mtn,同學只要下載 *.mtn 資料回去,就可以把課程的資料 (範例、文件與套件等) 都取出來。相當的方便,monotone 可以在某些場合取代 CVS 的使用,提供大家做參考。

比如我朋友 Andrew 拿到 jkbuilder-0928.mtn 後,要先用 mtn 做 "checkout" 的動作,這時 Andrew 下達的指令會是:

linux$ mtn --db=./jkbuilder-0928.mtn co --branch=org.jollen.dev

執行後,Andrew 就可以在 "org.jollen.dev/" 目錄下看到 checkout 出來的程式碼。Andrew 很熱血的幫我們改掉一下錯誤 (bug) 了!那我只要給 Andrew 一個簽證 (key),他就可以做 "commit" 的動作。

September 22, 2006

Embedded Linux 系統性的教學看法

依照建立 "root filesystem" 的方法,我們可以區分以下 4 大類型 (Jollen 個人看法,僅供參考):

1. Embedded Linux Distribution.
2. Hand-made.
3. Build system.
4. Metadata build system.

Embedded Linux Distribution

比如像是 Debian for ARM 這類型的 pre-built Linux distribution for embedded Linux 其實是不太實用的,除了 large-scale 的應用或是教學用途 (eg. PeeWeeLinux) 外,實務上並不是很經常使用這個方法。

Hand-made

就是純手工打造法啦!

在網路上 (特別是大陸網站下載的文件) 有很高的比率都是介紹如何採用 "hand-made" 的方式來建立 (bottom-up) root filesystem,不過這種方式雖然未來非常有可能不會再使用,但是絕對100%有必要去學習,幾個理由不外乎是:

(1) 透過 hand-make (aka Linux from scratch) 才能了解最根本的觀念。
(2) 透過 hand-make 學習到整體性的 embedded Linux 設計流程與方法。
(3) 能更深入學到建立 embedded Linux 系統的技巧。
(4) 練功。
(5) 練就建立 embedded Linux 系統的基本功,並學習所要具備的 Linux 系統管理能力。
(*6) very critical 的問題都要 hand-make 才得以解決。

這個方法是必學的,因為可以學到很深入的 cross-compilation 技巧,比如像是在 Jollen 課程裡提到的在某些類型的套件 "porting" 方式中,就要去修改 configure.in。

Build System

像是 Jollen 設計的「教具」Jollen-Kit! Builder 就是屬於這種類似,我們的 embedded Linux 課程是希望同學建立基本功,因此是由 hand-made 教起,課程的尾巴我們給同學 Jollen-Kit! Builder,並講解如何「有效率且系統化的做 cross compilation 與建立 root filesystem」。

Build system 大多建立在 Makefile 與 script 的體系之上,幾個知名的 build system,像是 uclibc-distribution、SnapGear、Buildroot (也經常被用來建立 arm-uclibc 的 toolchain) 等,都算是 build system。

Metadata Build System

這是一種更先進高階的 "build system",以往我們都用 Makefiel / script 來建立 build system,但這種方法 (傳統 build system) 的缺點是:

(1) 無法有效解決套件間的相依 (dependency) 問題。
(2) 支援多平臺 (architecture) 時,很麻煩的!
(3) 有時改 configure.in 改到頭痛!
(4) 甚致要把套件 (package) 的 source code 也一起打包,不能設計成網路下載 (像 cflinux 這樣)。
(5) ...還有很多很多...

目前最具代表性 (也找不到別人了) 的專案是 OpenEmbedded,我們在今年初開始試著用 OpenEmbedded 來建立 embedded Linux,雖然還有不足的地方 (有時沒有比 build system 方便),但是基本上 OpenEmbedded 已經完整展示了先進的 "Linux distribution for embedded system" 做法。

OpenEmbedded 採用 BitBake 來做套件的 cross compilation 與管理,BitBake 使用 .bb files 與 bbclass 來建立 Linux distribution。BItBake 的精神與觀念真的非常值得讚許,如果您曾經玩過 cflinux 或類似的 build system,一定會對 BitBake 與 OpenEmbedded 感到驚奇的。

雖然我們目前用 BitBake 來建立 metadata build system 還算小有收獲 (Jollen-Kit! Builder Enterprise),不過要讓大家都能很上手的深入 OpenEmbedded 系統去做客製化、修改或是加入套件,還是有點障礙的,畢竟這不像我們上課介紹的做法那麼直覺。

而且還要挑戰 GNU autoconf,這是一大惡夢呀。

學習旅途

Embedded Linux Distribution -> Hand-made -> Build system -> Metadata build system -> 玩家!

不過不一定每個階段都要去涉獵,有些對 Linux 系統很熟的玩家級同學,甚致直接切入 build system 的修改。

最後要來 push 一下 = ="

假設對 Jollen 的課程有興趣的話,請務必了解一下我們的課程規劃,或是使用 Email 由我們提供1-by-1的咨詢,才不會花冤枉錢。

September 25, 2006

RISC 嵌入式平臺 (PowerPC) 的 VGA 解決方案

從事系統程式工作的朋友大都聽過 Open Firmware 的標準,因為工作上的需要,允許 Jollen 可以花一點時間整理 Open Firmware 的資源。至於為什麼要來讀 Open Firmware,就要由 x86 的 VGA 說起了。

從以前我們做過的 PowerPC + x86 VGA 專案,以至於對 LinuxBIOS 玩票性質的研究,都能推導到一個未來 (也是現在) 值得投資的主題,那就是 Open Firmware。Jollen 最近發現在 OpenBIOS 的專案網站中,出現了一個 FCode Suite 的套件,這是 IBM 的 David Paktor 老兄在八月份 (2006) 丟到 OpenBIOS 專案的貢獻 (不過他在9月5日才發佈這項消息)。

OpenBIOS

OpenBIOS 的專案目的是實作一個 IEEE 1275-1994 (即 Open Firmware 標準) 相容的 firmware。OpenBIOS 提供的 FCODE Suite 將 ANS Forth 相容的程式碼翻譯成 FCODE 中介形式,可以提供我們開發 platform-independent 的 boot-time device drivers (可以看 David 的 email)。

這裡先暫時把相關的資源 (VGA) 再整理一下,等到公司的 PowerPC 平臺真的 ready 後,才可能有機會來 study FCode Suite。

Video Graphics Array

VGA BIOS 提供了一組 VGA 卡的服務函數,實作在主機板上的 BIOS 裡。非常早期的 IBM PC 就有提供 VGA BIOS (或稱為 Video BIOS)。VGA BIOS 主要是一大堆 screen I/O 的函數,這是 x86 架構下的產物,自然也就以 x86 assembly 寫成。

VGA BIOS 歷經歲月的擴充與積累,一直到 1987 年 VGA 出現為止,才大致成為現今我們所看到的樣貌。VGA 全名是 Video Graphics Array,VGA BIOS 也相容於之前的 CGA/EGA。

CGA - Color Graphics Adapter
EGA - Enhanced Graphics Adapter

VGA BIOS 透過 INT10H (10 號中斷) 來提供 DOS 程式在瑩幕上畫圖,以前學過 x86 assembly 的朋友一定都知道這號有名的中斷。標準的 VGA BIOS 提供以下的功能:

* CGA/EGA/VGA routines, INT 10H - 功能編號 00h~0Fh
* EGA/VGA routines, INT 10H - 功能編號 10h~13h
* VGA routines, INT 10H - 功能編號 1Ah~1Ch
* 標準的 VGA 參數表與字型表

另外,常常聽到的 "VESA" 全名是 Video Electronics Standards Association,這是一個制定 VGA BIOS Extensions 的組織,目前有主要的二份規格: VBE 2.0 (1994) 與 VBE 3.0 (1998)。VBE 制定現在耳熟能詳的 virtual screen areas 與 framebuffer 功能,像是 Linux 的 VESA Framebuffer driver (linux/drivers/video/vesafb.c) 便是能支援 VBE 2.0 compliant 的顯示卡 (因此 vesafb.c 是 x86 平台才能用的)。

以下是在網路上找到的 10 號中斷說明:

http://home.educities.edu.tw/wanker742126/asm/ap07.html
http://www.bookcase.com/library/dos/ints/int10.html

跟 x86 assembly 有關的:

http://www.csn.ul.ie/~darkstar/assembler/
http://burks.bton.ac.uk/burks/language/asm/asmtut/asm1.htm#toc

x86 中斷表

Ralf Brown's Interrupt List 這個實在是太有名了,就不多做介紹了,這位老兄整理的中斷服務表是以前寫 MS-DOS assembly 的寶典,以前還記得這份列表的最新更新都只透過 Fido Net 在散佈,所以以往 Dailup-BBS 的時代要找到這份列表都要去找台灣 Fido Net 的站台才下載得到。

現在這份列表已經可以由 WWW 很方便的下載了。下載的網址是http://www.cs.cmu.edu/afs/cs/user/ralf/pub/WWW/files.html

LinuxBIOS v.s. x86 VGA

這算是比較古老的議題了,而且也是屬於實作面的問題。

把 VGA 卡插到 PowerPC 平臺上後,當然是,不會動的!VGA BIOS code 要能在 RISC 平臺上執行,必須要有 x86 emulator,由於 VGA BIOS 是 INT 10H 中斷服務,所以除了能能模擬 x86 外 (instruction set),對於 INT 10H 與其它中斷的模擬也是必要的;另外就是 x86 上的 I/O port 要對應到 I/O memory。

LinuxBIOS 提供的 FreeVGA (Architecture Independent Video Graphics Initialization for LinuxBIOS) 應該是 x86 VGA 解決方案的第一選擇。不過我們以前的專案在摸擬 VGA 時,用的是 U-Boot + x86emu,在這裡我們使用的 x86emu 是 SciTech 的版本,目前只能由 SciTech SNAP SDK 取得。使用 U-Boot + SciTech x86emu 是第二選擇,也是我們用的方法。

September 27, 2006

libiconv: 字元集碼編轉換

實作 Linux 系統程式時,常需要做「Unicode 與 Big5」間的字元編碼轉換;嵌入式 Linux 的應用也經常會遇到這樣的需求,例如我們原則上會將文件存成 Unicode,當程式執行時,再決定要輸出成 Unicode 或 Big5 (or GBxxxx),這時就要使用到 GNU 的 libiconv 專案。

GNU libiconv 用來做字元間的編碼轉換,已經廣泛被使用在 GNU/Linux 系統中,例如 PHP 的 iconv 系統即是使用 GNU libiconv。libiconv 要移植到 ARM9 平臺上也是非常容易的。GNU libiconv 的官方首頁是: http://www.gnu.org/software/libiconv/

把 libiconv 套件解開並編譯後,可以在 src/ 目錄下找到 iconv 執行檔,這是 libiconv 為我們寫好的一個字元轉碼 (conversion) 工具,這個工具相當的實用,比如以 jollen 的網站來說,jollen.org 的網頁是以 unicode 儲存,但是我們發佈的頁面是以 big5 編碼為主,我們所使用的轉換工具便是 iconv。

iconv 的使用可以參考 http://www.gnu.org/software/libiconv/documentation/libiconv/iconv.1.html,我們舉一個例子來說明,比如我想把 big5.txt 文件 (Big5 encode) 轉換成 Unicode (UTF-8),那麼只要執行:

$ iconv -f BIG5 -t UTF-8 big5.txt

就可以了,參數 -f 指定來源編碼,參數 -t 指定目的編碼,編碼後的字串會輸出到 stdout。字元集 BIG5 也可以寫成 BIG-5,或是 BIG-FIVE,或是 BIGFIVE;要怎麼知道 iconv 可以處理 (接受) 哪些字元集 (character set ),只要執行 'iconv -l' 就可以查詢了,輸出結果會是一大票的字元集列表。

這是使用 iconv 工具的方式,假如要自己寫程式的話也是非常簡單的,因為 libiconv 裡頭只有 3 個函數:

iconv_t iconv_open (const char* tocode, const char* fromcode):開啟 libiconv。
size_t iconv (iconv_t cd, const char* * inbuf, size_t * inbytesleft, char* * outbuf, size_t * outbytesleft):執行轉碼。
int iconv_close (iconv_t cd):做完轉碼後關閉 libiconv。

libiconv-1.xx/src/iconv.c 本身就是一個很棒的範例了,大家可以參考。


September 28, 2006

QEMU 虛擬機器

QEMU 是一個可以模擬 x86、x86_64、ARM、、SPARC、SPARC64、PowerPC、PowerPC64、MIPS、m68k 與 SH-4 處理器的 open source 軟體。簡單說,QEMU 就是一套虛擬機器 (virtual machine) 的軟體。

QEMU 提供二種模擬模式:(1) Full system emulation;(2) User mode emulation。Full system emulation 模擬完整的系統,即處理器與週邊;user mode emulation 則是能在不同的處理器平臺上執行其它處理器平臺的程式。

以下是引用自 QEMU 官方的介紹:

QEMU is a generic and open source processor emulator which achieves a good emulation speed by using dynamic translation.

QEMU 的 Status 網頁表列了目前支援的 CPU 與這二種模擬模式的支援狀況。在 QEMU 的 roadmap 裡,也驚見 "Full MAC OS X support as guest OS" 的 計畫,真是令人期待。

網路上有人利用 QEMU 安裝了 Versatile,然後灌了一套 Debian ARM 在玩。看起來頗為有趣,此外,QEMU 應是目前最佳的模擬器首選,這真是學習微處理器系統的好教具。

September 30, 2006

Embedded Linux 是程式?是一台裝置?還是什麼?

Embedded Linux 倒底是什麼東西啊?最早 Jollen 的書曾經節錄國外專欄的解釋,企圖以最簡單的方式來定義「Embedded Linux」:Embedded Linux is a software platform for embedded system。因此,Embedded Linux 是一種「特殊的應用方法」,並不是一個程式。

今天在 LinuxDevices.com 的 forum 看到一則 post,原始發問者顯然誤解了 Embedded Linux 的意思,不過有位好心人很邁力地解釋 "regular Linux" 與 "embedded Linux" 的觀念,他的開場白寫的真的很不錯:

'Embedded Linux' is not an application program, it is a kernel and set of libraries and utilities designed to run on an embedded system(for example, a router).

真然是一針見血,講的真好。Embedded Linux 是一個 kernel (for specific-platform) 與一些 libraries/utilities 的集合 (即 root filesystem);因此所謂的 embedded Linux 通常是以一個 kernel image 與 root filesystem image 的形式 deliver 給 end-user 的。

其實初學 embedded Linux 的同學,也經常被 embedded Linux 的名詞所困惑,因為我們都假設大家對 embedded Linux 都有一定程度的「sense」了,所以很少去解釋 embedded Linux 與一般 Linux 的差異;在對初學者的教育訓練上,我們試著以「Top-down 最小化 Linux 系統」與 embedded Linux distribution (eg. PeeWeeLinux),再配合 PC Linux 與 embedded Linux 的差異比較來解釋「Linux (GNU/Linux) 系統應用於嵌入式裝置」的觀念,目前看來成效還算不錯呢!

由於嵌入式 Linux 是「Linux (GNU/Linux) 系統的特殊應用」,因此所有的基本技能 (enabling technologies) 是建構在傳統的 Linux 系統操作與管理能力上的;所以「學 embedded Linux 是不是就不用去學 Linux 指令與 Linux administration」問題的答案肯定是「NO」。

嵌入式系統開發導論 (刊載於 Run! PC 8 月份)

超熱門美食:嵌入式系統

什麼是「嵌入式系統」?這個熱到不行的題目倒底是什麼東西!嵌入式系統已經是全球科技業的共通話題了,就讓我們來簡單說明什麼叫「嵌入式系統」(Embedded Systems)吧。

美國工程師協會所定義的...嗯!看到這句話大家大概又要傻眼了,怎麼每個人解釋嵌入式系統都要搬出美國工程師協會的定義來交差呢!這真的是落伍啦。嵌入式系統不過是廣義還是狹義的定義,肯定都是包山包海的又臭又長。

我們這裡所要講的嵌入式系統目標是鎖定在熱門的「嵌入式作業系統平臺技術」(Embedded OS),所以如果我們再繼續縮小主題的話,沒錯!題目就只剩下 WinCE、Symbian 與 Linux 了!

如果以學習熱度來講的話,WinCE與 Embedded Linux 絕對是不「二」主題。所以我們要講的嵌入式系統就是Windows Mobile與Embedded Linux。本文將會明確鎖定幾個主題,並給予一個學習的方向,讓有志進入嵌入式系統領域的朋友能抓住主要的幾個主題。

功能導向的系統

言歸正傳,所謂的嵌入式系統簡而言之是一種「執行部份特定功能」的系統,實作上並不限定技術範疇,只要能將特定的功能(function)「嵌入」到目標裝置(target device)裡,包含這些功能的整體系統(或平臺)即是「嵌入式系統」。

一部目標裝置裡頭,可能會有數十個甚致數百、數千個嵌入式系統,每個「系統」均負責執行一項專責的功能。

由於目前的目標裝置都必須嵌入甚為複雜的功能,所以「嵌入式作業系統」成為嵌入式系統不可或缺的要素。例如,一支完全沒有生命力的「手機硬體」,在嵌入Windows Mobile與application後,就變成可以聽MP3、跟女朋友聊天、看MTV與使用各種功能的活力裝置了!有了完整的嵌入式系統技術,任何目標裝置都會因為嵌入式系統的注入,而產生生命,充滿活力!

目標裝置導向的系統

由於嵌入式系統是功能導向的系統,因此必須設計、選擇或購買正確(或適合)的目標裝置,才能開始實作並嵌入「嵌入式系統」。因此,嵌入式系統的技術是以功能與目標裝置為分類的一種技術。

例如,與PDA相關的目標裝置(即硬體)、與MP3撥放器相關的目標裝置、與3G手機相關的目標裝置等等;使用這些目標裝置所開發的特定功能系統,便是PDA的嵌入式系統、MP3音樂撥放的嵌入式系統、3G手機的嵌入式系統。

附帶值得一提的是,由於嵌入式系統的目標裝置,在硬體規格或架構上往往重疊性很大,所以很多SOC的廠商都會推出所謂的「公板」或「參考設計」(Reference Design),下游的開發者往往只要把公板做部份修改或小量的客製化,即可滿足自己的需求。

使用嵌入式作業系統

因為以功能為導向,因此當要嵌入的功能很複雜或非常多樣化時,使用嵌入式作業系統才能解決許多技術面的問題。有了嵌入式作業系統,「功能的實作」往往只是在「寫程式」,所以最終可以把嵌入式系統變成軟體開發的工作。

目標裝置 (Target Device) 的特性

嵌入式系統大多數都不使用標準的IBM PC硬體,而且有些嵌入式系統的目標裝置都是很特殊的。不過,我們可以將嵌入式系統目標裝置(target device)的主要硬體差異做一個說明。
我們透過與IBM PC的差異比較來做解釋。

嵌入式系統使用SOC(System-on-Chip)的處理器,這些SOC都是專為嵌入式系統或是手持行動裝置設計的,因此具備低功率、低耗電與面積小的特色。

在RAM方面,嵌入式系統的RAM大多在2MB到128MB之間,並且都是屬是SRAM/SDRAM的技術。很少使用IBM PC規格的DDR記憶體。

在儲存裝置方面,嵌入式系統採用NAND flash技術來存放系統程式。例如iPOD就有一部份產品使用NAND flash來存放MP3。使用NAND flash做為主要的儲存裝置是嵌入式系統的主要趨勢之一。
嵌入式系統主要透過序列埠輸出資訊;而個人電腦則是透過VGA顯示卡顯示圖形資料,嵌入式系統大多使用TFT-LCE做為圖形介面。

個人電腦當然是一般用途(general-purpose)的電腦,因此可以安裝許多有趣的應用軟體。嵌入式系統則是屬於特定用途(specific-purpose)的電腦,主要是針對特定功能所設計。

WinCE簡介

由於微軟的智慧型手機與台灣代工伙伴合作的成功,使得Windows Mobile成為大家耳熟能詳的嵌入式系統技術。那麼Windows Mobile與Windows CE到底是不是一樣的東西?

基本上,Windows Mobile與Windows CE是一樣的;Windows CE是微軟專為嵌入式系統所推出的embedded OS,Windows CE可應用於網路設備、Set-top-Box、工業控制器等嵌入式裝置。

Windows Mobile 5.0採用Windows CE 5.0的核心,是專為PocketPC與Smartphone所推出的產品。WinCE的開發環境可以相當低的花費取得,甚致可以取得免費版本;Windows Mobile的開發環境則是必須經由微軟授權後取得。

WinCE的產品開發門檻底、程式開發工具友善使用性佳、使用者介面豐富與完整的多媒體支援,使得WinCE在行動手持裝置的產品開發上具備相當的優勢。

以專為智慧型手機推出的Windows Mobile 5.0來說,除了使用性佳的操作介面與強大的多媒體撥放支援外,更可以執行Mobile Office套裝軟體(Word Mobile、PowerPoint Mobile Viewer等)、使用MSN與收發Email等。

Windows Mobile上能執行許多PC上常用的許多應用程式,例如:Mobile IE、Windows Media Player 10 Mobile 5,都是讓Windows Mobile智慧型手機更聰明好用的關鍵。在嵌入式軟體開發方面,Windows Mobile支援 .NET CF(Compact Framework);開發工具目前也整合成一套Visual Studio 2005,開發Windows Mobile的應用程式更加輕鬆愉快;需要資料庫應用的應用程式,也能使用SQL Mobile解決方案。

Embedded Linux簡介

Embedded Linux其實並不是一個作業系統,而是代表「應用Linux系統於embedded system」的名詞。因此用即是Embedding Linux來說明Embedded Linux技術是再恰當不過了。Embedded Linux的技術核心主軸是在研究「如何將Linux系統嵌入至嵌入式目標裝置裡」。

根據William E. Peisel 於Whitepaper: Embedding Linux一文對Embedded Linux的看法,Embedded Linux的定位為:「A software platform for embedded systems and devices」。

嵌入式Linux系統的技術主軸有二:(1) Linux kernel 與 (2) root filesystem。Root filesystem即是「小型的Linux系統」,root filesystem裡頭存放Linux的系統架構(filesystem hierarchy)、指令、工具、應用程式、shared libraries、驅動程式等。

Embedded Linux的root filesystem必須純手工打造(from zero / from scratch),因此熟悉Linux系統的操作、設定與管理是必要的基礎技能。

相較於WinCE友善的程式開發環境,Embedded Linux的開發環境則是比較不容易上手的。目前專門針對Embedded Linux的開發工具尚不成熟,因此我們都是在Linux的”PC”上使用Linux一般性的程式開發工具來進行嵌入式Linux的發展。

Embedded Linux的開發工具,主要以GCC和glibc為核心。GCC(http://www.gnu.org/software/gcc/gcc.html)是GNU Compiler Collection的縮寫,也就是許多編譯器的收集,目前支援的程式語言有:C、C++、Objective-C、Fortran 、Java、Ada。GLIBC是GNU的C標準程式庫,GLIBC提供system call的界面函數與標準的C函數。GLIBC也符合許多標準與規格,讓使用GLIBC的程式可以更容易移植到其它UNIX平臺。

目前應用Embedded Linux技術的產品,大多偏向「非手持型」的嵌入式系統,例如:網路設備、Set-top-box、工業控制器等。

Linux kernel

Linux 是一個作業系統核心的實作,Linux kernel 加上其它必要的系統工具 (utilities) 與其它專案程式碼的 Linux 作業系統則稱為 Linux system,一般認為標準的稱呼為 GNU/Linux (system),這是因為 Linux system 使用的系統工具大多是 GNU 的程式碼。

目前仍在使用本的kernel版本可分為4大分支:

1. Kernel 2.0.x:已經停止發展的早期版本。
2. Kernel 2.2.x:已經停止發展的早期版本。
3. Kernel 2.4.x:重要的版本分支,目前仍廣為使用中,因此仍然持續有驅動程式與處理器架構相關程式碼的更新。
4. Kernel 2.6.x:重要的Linux kernel里程碑,許多新技術、新觀念、驅動程式支援與作業系統架構都在此版本實作,是目前更新最頻繁的版本分支。

目前(2005年)的最新kernel版本為2.6.x系列,由於kernel的開發者很早就已經轉移重心至2.6系列,因此2.4系列的版本分支也將漸漸停止發展。許多2.4版本裡的重大bug也只在2.6系列版本做修正。

2.4 系列的 kernel 仍普遍使用於嵌入式系統中,但缺點是驅動程式的支援較不足;2.6 系列的 kernel 是目前最流行的分支,這個系列的 kernel 加入許多新技術的實作,當然也包含對嵌入式系統的支援,並且具備較完整的驅動程式。

Embedded Linux的重要規格標準

Embedded Linux是基於Linux系統的特殊應用,當然也要符合眾多標準才行。LSB與FHS標準是重要的二大標準,跟隨標準不但可以提供系統間的相容性,也可以提供我們一個Linux系統的建構依據。

由 FSG (Free Standards Group) 所主持的 LSB (Linux Standard Base) 專案即是在制定 GNU/Linux 的標準。根據LSB標準所發展的GNU/Linux系統,才能提供應用程式最小的可執行環境,並且可在依循LSB標準的Linux distributions上執行無誤。例如,我們可以在符合LSB標準的Red Hat Linux上發展應用程式,只要自行發展的Embedded Linux系統符合LSB標準所訂定的規範,應用程式就可以順利移植到Embedded Linux上執行。

LSB 標準也提供我們發展 Embedded Linux 的依據,雖然 Embedded Linux 系統是最小化的 Linux,但因為 Embedded Linux 是嵌入式系統的軟體平臺,所以我們不能任意精簡 Linux 系統,在精簡的過程中仍要保留最基本的作業系統環境,而 LSB 的標準正是在制定這些基本的需求。

LSB Specification共分成二大類型:

1. Generic Specification(LSB-generic):定義不會經常改變與各處理器同通之一般標準。
2. Architecture Specifications(LSB-arch):定義不同處理器架構之標準。

完整的 LSB 規格文件為 gLSB 配合特定的 archLSB 文件,若我們以 IA32 之電腦架構為主,應選擇參考 LSB Common 與 LSB IA32 二份文件。

LSB - http://www.linuxbase.org/spec
如何進行LSB 3.0的認證測試:http://www.opengroup.org/lsb/cert/docs/LSB_Certification_Guide.html

FHS 全名為 Filesystem Hierarchy Standard,是一份定義檔案與目錄標準的文件,FHS 的標準定義了目錄與檔案的擺放位置,而 UNIX-like 的系統則是根據這個標準來管理整個檔案結構。因此,不管是系統廠商、Linux/UNIX distribution 發展者、應用程式作者、套件管理者、系統維護人員都應該要依照 FHS 的標準來管理 UNIX 系統的目錄與檔案。

豐富的Free Software資源

Embedded Linux的特色是大量使用Free Software的資源,「任何你想要的軟體,幾乎都能在網路上找到自由軟體」已經成為Embedded Linux技術的重要支柱。自由軟體資源包山包海,舉凡應用程式、系統工具、網路工具、程式庫、圖形介面、小型瀏覽器、程式發展工具等等都能找得到。

因此學習Embedded Linux有一個很重要的階段就是「玩Linux!」,了解Linux的世界有什麼軟體可以用,對於將來發展Embedded Linux有絕對的幫助。甚致更進一步去學習別人寫程式的技巧,都能累積Embedded Linux的功力。

-- 作者/陳俊宏 (jollen)
原文刊載於 Run! PC 雜誌 8 月號
歡迎任意轉貼引用.但請務必註明出處

最精彩的一道菜:驅動程式

軀動程式本身是屬於「軟體硬介面」的程式設計技術,不管是學習WinCE或是Embedded Linux,最精彩的部份絕對是驅動程式莫屬。由於嵌入式系統整體來看,除了軟體開發外,也包含硬體的客制化,因此驅動程式在嵌入式系統技術領域中,佔了舉足輕重的地位。

學習驅動程式需要確實瞭解硬體的規格與微處理器架構,並且工程師還要能分得清楚哪些東西是介面(interfacing)也就是與硬體無關的程式(machine-independent);以及哪些是站在第一線做硬體控制的程式(machine-dependent)。各種軟體硬介面與滙流排也都要精通。

現在的嵌入式系統學習主軸

現今嵌入式系統的實作,幾乎都會加入嵌入式作業系統(embedded OS)的元素,有了作業系統,我們都可以為目標裝置「寫軟體」。總合來看,如果要學習所謂的嵌入式系統,從熱門的WinCE或Embedded Linux領域切入是相當不錯的選擇。

驅動程式是「寫軟體」與「做硬體」的 “connectivity”,因此現今資訊業界最熱門的嵌入式系統學習主軸為驅動程式的設計。

WinCE驅動程式

WinCE驅動程式的核心人物當然就是在WDM(Windows Driver Model)身上了。WDM是Windows 98/2000之後的驅動程式架構,WDM是一個嚴密的分層(layered)架構,架構層間以IRPs(I/O Request Packets)做通訊。

WDM驅動程式分為三種類型:bus driver、function driver與filter driver。Bus driver是device-independent的驅動程式,主要在驅動I/O bus,例如:PCI bus driver、USB bus driver;function driver是 “device” 的驅動程式,我們常講的「驅動程式設計」大部份都是講 function driver,function driver 主要在驅動各種裝置,因此大多是由裝置廠造商撰寫並提供給使用者安裝,function driver 的設計大多著墨在「讀/寫」外部裝置。Filter driver是非必要的驅動程式,主要在過瀘 I/O requests。

WDM驅動程式的設計是使用Windows DDK,學習資源豐富並且完整;相較於Linux驅動程式,WDM驅動程式的學習材料較系統化。

Linux驅動程式

Linux驅動程式採取嚴謹的分層式架構設計(layered architecture),利用分層的架構設計來徹底區分generic device driver(machine independent)與machine dependent driver。

Linux驅動程式採用分層架構的觀念設計,透過「註冊」與「回呼」的機制來清楚地區分每一層的關係。分層架構的實作必須在下層將自己註冊給上層,上層再回呼下層;上層的驅動程式必須提供註冊函數供下層呼叫,下層驅動程式所使用的註冊函數也將決定自己的上層架構。

與 user application 如何互動,是撰寫驅動程式時所要考慮的重要一環,因此在撰寫驅動程式時,要提供什麼「功能」給應用程式引用,就必須事先定義清楚。Linux的generic device driver層已經幫我們把這些功能定義清楚了。Linux驅動程式如何透過 I/O port 或 I/O memory來控制裝置,也就是與晶片組的溝通,方式是使用 Linux kernel 所提供的I/O函數來存取並控制實體硬體裝置。

Linux驅動程式的學習困難度較高,並且也沒有像是Windows DDK這樣的完整開發工具;但是若能掌握正確的學習步驟,要邁向高手之路並非遙不可及。

-- 作者/陳俊宏 (jollen)
原文刊載於 Run! PC 雜誌 8 月號
歡迎任意轉貼引用.但請務必註明出處

Linux smartphone 之路

相較於Microsoft的Windows Mobile的成功,過去的Linux smart phone 之路顯然有點坎坷。雖然大敵在前,但是Linux開發社群對Linux手機的熱情絲毫未減。終於,去年(2005)年,由11家Linux與處理器大家共同成立的Linux手機標準論壇(Linux Phone Standards Forum – LiPS)提出具體的Linux smart phone架構圖。

LiPS發起廠商共有11家大廠,分別是:ARM Ltd., Cellon, Esmertec, France Telecom/Orange, FSMLabs, Huawei, Jaluna, MIZI Research, MontaVista, Open Plug, and PalmSource。最近又加入了Texas Instruments、ZTE、Telecom三家大廠。

figure_02.gif
圖: LiPS 的工作範圍(kernel 部份是OSDL的任務)
(Source: LinuxDevices.com / LiPS)

LiPS的主要任務為「標準化(standardizing)Linux手機」,並提出可行的Linux手機OS架構。更明確來說,LiPS在標準化「Linux手機的middleware層」,middleware提供電話功能的API、GUI、裝置管理功能、相關的安全性管理、電話簿功能。今年下半年將可以看到LiPS釋出的第一版Linux手機規格!

除了LiPS外,OSDL(Open Source Development Labs)也未曾缺席Linux的手機發展,OSDL裡的MLI(Mobile Linux Initiative)也於2005年成立,MLI的任務為「maximize the market opportunity for Linux-based devices」。目前的成員有:MontaVista Software, Motorola, PalmSource, Trolltech, Wind River。

LiPS與OSDL的合作相當密切,LiPS著重moddleware的規格定義,OSDL的MLI則是著墨於kernel層。MLI的任務是發展出適合Linux mobile phone使用的kernel,LiPS的任務是發展出明確的手機軟體架構(software stack)。

Mobilinux 4.0

Mobilinux是目前可以取得,最具體的Linux手機產品。

Mobilinux 4.0是MontaVista的新一代主力產品,Mobilinux 4.0其實是由MontaVista原先的Linux Consumer Electronics Edition (CEE) 3.1 與 Linux Consumer Professional Edition (Pro) 3.1 產品所延伸而來的新一代Linux mobile phone OS。

Linux Consumer Electronics Edition (CEE) 3.1 與 Linux Consumer Professional Edition (Pro) 3.1 已是 design win 的產品,市面上可看到十多款的手機產品。

Mobilinux 4.0使用2.6系列的kernel,real-time的支援與效能表現比以往更優秀,Mobilinux 4.0也承習Linux CEE的電源管理(power management)強化功能。Mobilinux 4.0的real-time patch是Open Source Real-time Linux Project的成果。

* Mobilinux - http://mobilinux.com/
* Linux 手機展示場 - http://www.linuxdevices.com/articles/AT9423084269.html

kernel 2.6的一個重要特色是:支援SD/SDIO/MMC,Mobilinux 4.0也強化對SD/SDIO/MMC的支援,對於Linux手機的應用是相當重要的里程碑。

figure_03a.jpg

figure_03b.jpg

figure_03c.jpg

figure_03d.jpg

figure_03e.jpg

圖: 基於 Mobilinux 的 Linux 智慧型手機(由上至下依序是:Motorola A728、Motorola E680、NEC N700i、NEC N902i、Panasonic P902i)

目前Mobilinux的design win手機產品有15支,所有的Mobilinux Linux手機可以到Mobilinux網站查詢。

-- 作者/陳俊宏 (jollen)
原文刊載於 Run! PC 雜誌 9 月號
歡迎任意轉貼引用.但請務必註明出處

嵌入式OS的重要共通議題

學習WinCE與Embedded Linux的重要課程是「系統程式」(system software)的觀念,不管是WinCE還是Embedded Linux,有幾個核心的系統程式或作業系統基礎,絕對是要用力研究的。

第一個是process的觀念,process是執行中的程式,如何控制process(生成與刪除)、非同步的signal處理等;第二個是process synchronization的觀念,process是concurrent(同步)在執行,所以會產生race condition(競賽問題)問題,解決race condition現象的方法、semaphore、monitor、mutual exclusive、locking等,是這個觀念主題的重點。

第二個是thread的程式設計方法與thread同步的方法,配合multi-threaded所實作的event-driven軟體架構,還有更進階的event manager的做法,是這個部份的重點。
因此,有志進入嵌入式系統領域的讀者,可以直接由WinCE或Embedded Linux技術切入,首先當然要以軟體層的學習為主,並且加強作業系統與系統程式這二門學科的能力,接著把最好的一道菜—驅動程式—徹底學通後,絕對能在嵌入式系統領域有所發揮。

-- 作者/陳俊宏 (jollen)
部份原文刊載於 Run! PC 雜誌 8 月號
歡迎任意轉貼引用.但請務必註明出處

關於 September 2006

此頁面包含了在September 2006發表於Jollen's Blog的所有日記,它們從老到新列出。

前一個存檔 May 2006

後一個存檔 October 2006

更多信息可在 主索引 頁和 歸檔 頁看到。

Top | 授權條款 | Jollen's Forum: Blog 評論、討論與搜尋
Copyright(c) 2006 www.jollen.org