顯示具有 arm 標籤的文章。 顯示所有文章
顯示具有 arm 標籤的文章。 顯示所有文章

2007年10月21日 星期日

EGLIBC於S3C2410 ARM SoC的體驗

稍早於「EGLIBC初探」提過CodeSourcery與諸多系統廠商合作,針對glibc的改進計畫 (自2.5版開始),實做出更適合Embedded環境的C Library實做 ── EGLIBC,前文也提及快速建構的script,而OpenEmbedded也正式納入對EGLIBC的支援。所以現在要建構與測試都可以相當快速,以下是參考的option groups組態:

jserv@venux:/home/moko/build$ cat ../org.openembedded.dev/packages/glibc/eglibc-svn/option-groups.config
# This file sets default values for all option group variables
# mentioned in option-groups.def; see that file for a description of
# each option group.

OPTION_EGLIBC_ADVANCED_INET6 = n
OPTION_EGLIBC_BSD = n
OPTION_EGLIBC_CATGETS = n
OPTION_EGLIBC_CHARSETS = n
OPTION_EGLIBC_DB_ALIASES = n
OPTION_EGLIBC_ENVZ = n
OPTION_EGLIBC_FSTAB = n
OPTION_EGLIBC_GETLOGIN = n
OPTION_EGLIBC_INET = y
OPTION_EGLIBC_LIBM = y
OPTION_EGLIBC_LOCALES = n
OPTION_EGLIBC_LOCALE_CODE = n
OPTION_EGLIBC_NIS = n
OPTION_EGLIBC_NSSWITCH = y
OPTION_EGLIBC_RCMD = n
OPTION_EGLIBC_SPAWN = n
OPTION_EGLIBC_SUNRPC = n
OPTION_EGLIBC_UTMP = y
OPTION_EGLIBC_UTMPX = n
OPTION_EGLIBC_WORDEXP = n
OPTION_POSIX_REGEXP = y
具體的細節可參考Jim Blandy發表於mailing-list的文章「EGLIBC size measurements for option groups」,EGLIBC透過option groups可讓C runtime的建構更加模組化,可輕易挑選Embedded環境所需的特徵,大幅降低code size與memory footprint,以常見組態來說,後者相較於glibc縮減為85%。筆者實際在openmoko GTA01bv4硬體 (based on S3C2410 ARM SoC)測試,在Smartphone的使用情境中,free memory從原本58444 bytes (glibc) 增加到67404 bytes (eglibc),幅度達13%,功能卻沒有因此打折,這與uClibc或其他小型的C Runtime來說,是很大的優勢。

取得筆者建構的EGLIBC-based openmoko 2007.2 image:http://people.openmoko.org/jserv/images/

2007年7月31日 星期二

SLC ECC Correction in S3C2440

S3C24xx都內建有NAND Flash Controller,而且都支援NAND Flash Boot。NAND Flash 和NOR Flash 相比,除了不能用linear addressing的方式來access外,就是NAND Flash有「允許bit error」的特性,所以在實際的使用上,就要配合ECC 來correct。

NAND Flash Controller中NFECCSAT0就NFESTAT0 (0x4E000024) ,用來表示以下:

  • Main Area
  • Spare Area
兩個區域的「哪個byte中的哪個bit是錯的」,這就是NAND flash Controller提供的hardware ECC 功能。

S3C2440只支援SLC,因為只有內建1 bite ECC,也就是說只能correct 1 bit的錯誤。S3C2443則內建4 bit的ECC,最多可以correct到4 bit的錯誤,所以可以support MLC。

SLC和MLC除了1 time programming的限制外,就是容易產生的Error bit 數。
  • SLC保證 99.9999% 的chip 只會產生最多 1 bit的error。
  • MLC要到99.9999%的程度,會有 4 bit error。
(以上的% 是僅供參考)

回到NFESTAT0,要correct bit error,首先要check一下 error的狀態,以bit[1.0],[3.2] 分別代表兩個區域的error狀態:
  • 00 : No Error - Lucky
  • 01 : 1 bit error - Correct 回來
  • 10 : Multiple error - 沒救了
  • 11 : ECC area error - 沒救 (?)
所以,需要作ECC correct的,只有在 01 的時候。

然後讀出 Error bit 所在的byte位置和bit位置,分別是
  • Byte 位置 bit[17:7], bit[24:21]
  • Bit 位置 bit[6:4], bit[20:18]
所以correction 的動作
 *(ReadBuf + ByteNo) ^= ( 1 << BitNo ) 

SECCD 就是 Spare-area ECC Data
MECCD 就是 Main-area ECC Data

2007年7月30日 星期一

Baudrate set in S3C2443

S3C2442 的UART Baurdate可設定的更細微,提供兩個register :

  1. UBDIV : 整數部份
  2. UDIVSLOT : 小數部份
設定的計算為:
整數 + 小數 = SRCCLK/ (baudratex16) - 1
以115200, SRCCLK=40MHz為例
整數 + 小數 = 40000000/(115200 x 16) - 1 = 20.7
所以
整數 = 20
小數 = 0.7
因此,UBRDIV = 20

小數部份與UDIVSLOT的關係是
小數 = UDIVSLOT 中 bit是1的數量 / 16
所以
0.7 = 1's number in UDIVSLOT / 16
1's number in UDIVSOLT = 11
UDIVSLOT有很多種組合,只要讓1的個數是11即可,Samsung建議,個數為11時,UDIVSOLT用 0xDDDD。

2007年7月28日 星期六

筆記:Into Idle

在設定完chip register,進入idle mode後,還要program co-processor:
這一篇 http://nocash.emubase.de/gbatek.htm 有說明到ARM CP15 Cache Control。

Cn,Cm,Op2 Rd   Command
C7,C0,4 0 Wait For Interrupt (Halt)
另外在linux kernel code中也有:
/*
* cpu_arm926_do_idle()
*/
.align 5
ENTRY(cpu_arm926_do_idle)
#if defined(CONFIG_CPU_ARM926_CPU_IDLE)
mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
#endif
mov pc, lr
ref SystemIdle Function:
MMU_WaitInterrupt(void)
mov  r0,#0x0
mcr p15,0,r0,c7,c0,4
mov pc,lr
所以,這是要cache 進入idle mode,等待interrupt 的意思 ?

S3C2412有三種Power mode:
  1. IDLE
  2. STOP
  3. SLEEP
是利用PWRMODECON 這個register來設定。

說是這樣說,但是Samsung的BSP code卻沒有這樣作,完全沒用PWRMODECON,反而是用 PWRCFG。其中的STANDBYWFI 佔2 bit,設定後,可以進入:
  • IDLE : 01b
  • STOP : 10b
  • SLEEP : 11b
這種利用寫入 PWRMODECON 的STANDBYWFIbit 的作法,在datasheet 中稱作是 "mcr p15, 0, r0, c7, c0, 4"。

datasheet 中「很好心」地為大家提供一個 "alternat method to set STANDBYWFI" :就是用剛剛的cp15 command:

mcr  p15,0,r0,c7,c0,4
但是沒有說明相當於command的哪一個信號? 01b, 10b, 11b ?

對照datasheet和BSP code:

STANDBYWFI 進入IDLE是 01b。
BSP code用 mcr cp15 command 進入時,Rd (在此用r0),卻是設定成 #0x0。

而且這是datasheet中有關"進入STOP Mode"的說明中寫的,BSP code卻是在進入idle mode 的code中使用的。

接著有一個table,說明進入三個mode的方法:
  • IDLE - STANDBYWFI
  • STOP - CMD or STANDBYWFI
  • SLEEP - CMD or STANDBYWFI
STANDBYWFI 的意思大概可瞭解,雖然有點不清楚,那麼"CMD"是什麼 ?是寫入command到PWRMODECON的MODESLEEP 嗎?

2007年7月27日 星期五

External Interrupt in S3C2440

S3C2440的EINT (Extend INT)中斷示意
s3c2440int

EINT也算是SUB INTERRUPT,但是完全沒有相似於SUBSRCPND的解說。只有register 說明,而且是安排在GPIO的部份... (好吧,該GPIO的mux function有Interrupt,所以算OK吧)。

偉大的EINT的registerg的說明中,EINTMASK、EINTPEND這兩個register只有table,沒有多餘的說明。

本來以為EINTPEND是指「經過mask後的interrupt」,結果不是,是mask前。所以要處理 EINT時要這注意,要將 EINTPEND和EINTMASK「處理」後,才是真正產生中斷的中斷源。


跟trigger mode有關係,當是外部controller觸發,設定成edge trigger時,因為未回應外部controller時,trigger signal不會改變,不會再有一次edge波形發生,所以即使先ACK這個INT也沒關係。反而是未能要能正確,無漏失的catch next edge,ISR要儘快的ACK這個interrupt,免得edge 出現時,interrupt還未ACK而miss。

.. 真是麻煩呀...

這樣的連動是不是要用class包裝起來?當設定edge trigger,該isr先ACK。當設定level triiger,作post ACK?

回到上面的圖,SRCPND經過priority arbitration,Mask後,選出一個bit 到INTPND。實際產生中斷。

INTPND和SRCPND都是要「手動」清除的。
DataSheet (14. Interrupt Controller - Interrupt Pending Register) 是說..
Like the SRCPND register, this reister has to be cleaned in interrupt service routine after cleaning the SRCPND register.
所以,中斷發生後,一定要clear SRCPND和INTPND。而且順序是
  1. SRCPND
  2. INTPND
原因和上面說的一樣..如果先clear到INTPND,但是SRCPND還沒清,則同一個中斷馬上又從SRCPND浮上來,導致一樣的INTPND。

2007年6月28日 星期四

親手打造Tablet / WebPad

從事嵌入式系統開發,很大層面就是想體會「親手打造」的成就感。以往最大的問題就是進入的門檻較高,不僅得有開發硬體,還得要耗費大量的時間進行驗證測試,然而,這些繁瑣的過程會讓我們失焦,是的,最重要的部份,還是賦予硬體生命的軟體,這才是具備長遠價值的產物,一旦有了足夠的經驗與系統軟體,要在相容的硬體移植或加強功能設計,那就如魚得水了。

之前選定一個用以「練功」的題目「構想:Embedded Linux + Mozilla」,作法可有很多種,不過筆者嘗試以系統模擬的途徑,驗證「視覺化系統模擬與偵錯」一文中提出的概念:引入針對嵌入式裝置的基礎建設,作以system prototype、進階分析,以及快速軟體開發之用。上個月則於討論群組提出具體的想法「RFC: Tablet/WebPad 參考設計」,目前已稍有成果,在Google Code Hosting上申請了新專案「mind - MIND stands for "Mind Is Not a Device"」,可透過OpenEmbedded的迷你子集合去建構整個Embedded Linux作業系統,並調整為Tablet / WebPad的系統組態,以Xscale與x86作為參考開發的硬體平台,本階段已可使用Qemu為基礎的系統模擬進行驗證 (GNU Toolchain、Emulator,與Debugger均移植到Win32),以下是運作中的展示畫面:

這呈現了我們Embedded Linux平台的應用程式,即精簡版的Mozilla web browser,輔以XUL打造進階的使用者介面。這個系統主要是作概念性呈現,所以其他應用程式則相對單純,程式主畫面如下:
待作事項:
  • 針對ARM平台規範新的虛擬硬體組態,加入Wifi / Bluetooth裝置模擬
  • 加入網路管理程式,如Linetconf
  • 透過內建的OProfile進行深入的效能調校
  • 提供x86 LiveCD

2007年6月25日 星期一

模擬Linux on Palm 5

Palm產品家族自第五代開始,部份採用Intel Xscale處理器,日前qemu的CVS tree也正式納入支援,於是熱血的hackers又開始鑽研是否可模擬Palm 5的硬體,並在其上運作Linux。在一番嘗試後,Alex很高興跟大家宣佈這個訊息,請見「Testing Linux4Palm on qemu」一文。他在 Hack&Dev計畫 (目標即是將Linux移植到原本運作PalmOS的硬體環境) 的程式碼加入以qemu為基礎的Palm 5的硬體模擬器,目前支援的硬體列表如下:

  • palmtc - Palm Tungsten|C (PXA255)
  • palmz72 - Palm Zire72 (PXA270)
  • palmtx - Palm TX (PXA270)
  • palmld - Palm LifeDrive (PXA270)
取得與編譯方式如下:
# svn co https://hackndev.svn.sourceforge.net/svnroot/hackndev/qemu/trunk qemu-hnd
# cd qemu-hnd
# ./configure --target-list=arm-softmmu --cc=gcc-3.4
# make -j2
預先取得必要的核心與檔案系統影像檔,假設解開壓縮檔後位於./palm/0.0.3-fnw目錄,則可透過以下方式執行: (其中一個hardware model)
$ cat RUN.sh
#!/bin/sh
BASE_DIR=`pwd`/palm/0.0.3-fnw
./arm-softmmu/qemu-system-arm \
-M palmld \
-kernel $BASE_DIR/zImage \
-sd $BASE_DIR/Angstrom-opie-image-palmld-0.0.3-alpha.rootfs.ext2 \
-append "root=/dev/mmcblk0 psplash=false"
啟動畫面如下:
過程中可透過qemu作LCD panel與終端機顯示 (serial) 的切換,也就是 Ctrl-Alt-[13]。以下是終端機操作畫面:
系統模擬越來越多元了。

2007年5月23日 星期三

ARM模擬的狀態保存

前文「透過USB連線與OpenMoko模擬裝置互動」指出現在透過qemu來模擬openmoko已有相當便利的互動機制,我們也隨時可在Qemu Monitor中監看與控制虛擬機器的狀態,Andrzej Zaborowski最近實做了ARM模擬的狀態保存,所以現在可快速load/save vm,如此一來,應用程式的開發與驗證更加便利。目前也整合到openmoko-emulator中,取得最新的發展版本:

$ svn co https://OpenSVN.csie.org/openmoko_addons/openmoko-emulator
現在openmoko/run.sh這個script已處理qemu-img的操作,所以我們只要如往常一般編譯與執行即可。舉例來說,我們希望保存開機完成、見到整個OpenMoko UI的狀態,那麼只要按下Ctrl-Alt-2以切換到Qemu Monitor畫面,在提示符號下先暫停虛擬機器的系統模擬動作:
(qemu) stop
接著就可以保存狀態:
(qemu) savevm mainwindow
參數 "mainwindow" 只是一個識別名稱,事實上我們可以在不同的狀態給予特定的識別,這時候我們可以結束虛擬機器的執行:
(qemu) quit
然後我們重新啟動openmoko-emulator (run.sh),立刻切換到Qemu Monitor,隨後在命令提示打入指令以查看保存的狀態:
(qemu) info snapshots
應該會得到類似以下的輸出:
Snapshot devices: mtd
Snapshot list (from mtd):
ID TAG VM SIZE DATE
1 mainwindow 22M 2006-05-23 11:11:35
要還原已保存的狀態相當直覺,只要打下指令:
(qemu) loadvm mainwindow
再按鍵Ctrl-Alt-1切回執行畫面,這時候就可以看到上次我們保存的狀態與畫面了,當然,配合前次提到的Linux gadgetfs,我們還可存取USB (emulated) network,這樣進行應用程式開發的彈性也提昇許多,若再引入自動化的機制,未來要實做「時光機器」也是相當可行的。

2007年5月21日 星期一

EGLIBC初探

在Embedded的環境下,我們有許多C Library的選擇,從BSD libc、uClibc、glibc、dietlibc,甚至是klibc (配合initramfs),過去我們考量到footprint,往往會捨棄發展活躍的GNU C Library (glibc),轉而以uClibc或dietlibc來建構系統,正如uClibc的FAQ網頁提及的項目 "What's wrong with glibc?" 所說:

"The GNU C library is a great piece of software, make no mistake. It is compliant with just about every standard ever created, and runs on just about every operating system and architecture -- no small task! But there is a price to be paid for that. It is quite a large library, and keeps getting larger with each release. It does not even pretend to target embedded systems. To quote from Ulrich Drepper, the maintainer of GNU libc: "...glibc is not the right thing for [an embedded OS]. It is designed as a native library (as opposed to embedded). Many functions (e.g., printf) contain functionality which is not wanted in embedded systems." 24 May 1999"
以及下一條 "So uClibc is smaller then glibc? Doesn't that mean it completely sucks? How could it be smaller and not suck?" 所說:
"uClibc and glibc have different goals. glibc strives for features and performance, and is targeted for desktops and servers with (these days) lots of resources. It also strives for ABI stability. On the other hand, the goal of uClibc is to provide as much functionality as possible in a small amount of space, and it is intended primarily for embedded use. It is also highly configurable in supported features, at the cost of ABI differences for different configurations."

所以很明顯,glibc考量到通用性系統的需求,許多部份會考量到效能的最佳化處理,所以光是字串函式往往就可能拆成許多程序來實做,以針對不同的資料量給予最佳效能的處理方式,但往往也必須付出大量的footprint衝擊。Greg Alexander甚至寫了一篇用詞尖銳的文章 "GLIBC SUCKS" 來闡述他的觀察:就算是簡單只用printf()函式的 "Hello World" 程式,竟然也不成比例的龐大,引述如下:

Let's perform some more GLIBC2 vs. BSD libc comparisons:

[greg@linux] ~$ gcc -static -o hello hello.c; strip hello
[greg@linux] ~$ du -sk hello
416 hello
compared to:
[greg@freebsd] ~$ gcc -static -o hello hello.c; strip hello
[greg@freebsd] ~$ du -sk hello
44 hello
Yeah, that's right, when statically linked GLIBC2's printf() and support routines are about 10x as big as BSD's. We're on computers, a 15% improvement is considered worth looking at so you can copy their techniques. An "order of magnitude" is 2x. You simply aren't expecting 10x differences between extremely simple code that hasn't advanced, technologically, in more than two decades.
可見如此簡單的應用程式,其空間使用竟然達十倍之譜,在筆者的「深入淺出Hello World」系列演講也提及許多glibc與gcc潛藏的神秘性質,這些對於有特定目標、空間侷限的系統來說,是很難允許的。但採用非glibc的解決方案雖可大幅降低footprint與系統複雜度,卻可能因而限制可用的應用程式,最有名的例子就是Mozilla一直無法在uClibc上正確編譯與執行,這也辜負了採用GNU/Linux作為Embedded system作業系統的美意。過去我們得因應需求與彈性考量,多方取捨並周旋於前述的C Library實做中。

專注於GNU開發工具研發與客制化的CodeSourcery公司與若干嵌入式系統大廠,諸如MontaVista、Freescale,及WindRiver等廠商合作,針對glibc的改進計畫 (自2.5版開始),實做出更適合Embedded環境的C Library實做 -- EGLIBC,並承諾與glibc的binary/source compatibility,其明確的目標可參考EGLIBC::Mission網頁:
" Expand and enhance the capabilities of the GNU C Library (GLIBC) to support embedded systems for diverse environments, and maintain an open development environment encouraging broad, cooperative developer participation."
所以採取同樣的codebase (svn merged from FSF),同時也確保是Free Software (copyright holder為FSF),在mailing-list也可見到「借力使力」的發展模式,如Joseph S. Myers的post "[patches] EGLIBC 2.6 created"。Jollen兄日前在「Embedded Device 等於 PC」一文提及以下概念:
「就現代的硬體來說,embedded device 和 PC 的界線是越來越小了,雖然有時參與的 project 是 'embedded device',但是技術本質上就好像在做 PC 一樣。」
這是非常有趣、值得思索的趨勢,拜硬體蓬勃發展所賜,我們得以在此時間點大量採用原本桌面系統的軟體建設,知名的OpenMoko計畫就是最好的明證,但畢竟嵌入式系統的考量仍有差異,所以今日我們有以下發展理念:
  • 銜接活躍的自由軟體開發
  • 不只採用開放的系統,更要有開放的發展心態
  • 將力量集中於刀鋒上,創造核心價值
這使得採用EGLIBC成為多贏的解決方案,於是OrzLab也開始評估這些嶄新技術。延續之前的分析與模擬驗證 (詳見「視覺化系統模擬與偵錯」一文),最近的重心放於ARM Embedded ABI、GCC 4.2,與EGLIBC等最新的技術,為了簡化進行流程,我改了簡單的script:toolchain-eglibc.sh,這可自動擷取原始程式碼並建構。執行方式很簡單:
./toolchain-eglibc.sh arm
成功編譯後,會在$HOME/cross-build/arm-none-linux-gnueabi目錄下建立以下子目錄:
  • obj : 建構過程的目的檔,可忽略
  • tools : 包含GNU Toolchain
  • sysroot : 置入target的Runtime (root file system)
稍後筆者會探討如何利用系統模擬器來驗證,並探討整體效能與記憶體使用的提昇。

Update: Jick的更新與修正可參考「EGLIBC: Embedded GLIBC 体验」