Embedded Linux: Introduction
-
Upload
jollen-chen -
Category
Education
-
view
3.752 -
download
6
description
Transcript of Embedded Linux: Introduction
嵌入式Linux系統簡介
u-boot,kernel,drvier,rootfs操作示範
Jollen’s Consulting
與優質的課程平臺商合作, 專注課程研究與開發,致力創造教育訓練的價值
課程供應與開發者,致力於價值創造詳細資訊: www.jollen.org/consulting
專業課程供應
歡迎參加由 Jollen’s Consulting 所規劃與主講的課程,參加我們任何課程,您皆可透過 [email protected] 信箱登錄個人資料,即可加入郵件列表;郵件主旨請填寫 [加入郵件列表]、郵件內文空白即可
我們將不定時提供以下資訊:
公開的講義電子檔 題庫系統使用帳號 實作測試題目(提供學員練功題目)
Jollen’s Consulting Team
嵌入式 Linux 系統簡介
Jollen Chen (陳俊宏)
Email:[email protected]
Blog:jollen.org/blog
課程時間:2009.09.15
主辦單位:佳士達.Jollen’s Consulting
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting
授課計畫
課程主旨:
針對Embedded Linux系統所涉及的實作進行簡介
課程主題:
Cross Toolchain & Root Filesystem 簡介
Kernel 編譯與除錯簡介
U-Boot 簡介
Linux Device Drivers 實作簡介
5
Cross Toolchain & Root Filesystem 簡介
6
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 7
Jollen-Kit! Pro. 開發板Jollen-Kit! Pro.(JK2410)是根據
SMDK2410參考設計(reference
design)所實作之Embedded Linux
+ARM9平臺。
SMDK2410是Samsung MCU
Development Kit for S3C2410的縮
寫,SMDK2410是一個非常完整的
Samsung ARM9 Reference Design。
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 8
InterfaceI2C介面1組。
SPI介面1組。
GPIO介面共3組:12個button,4個方
向鍵與一個GPIO pin house連接頭。
Touch screen介面1組。
Touch screen ADC介面1組。
S3C2410 JTAG介面1組。
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 9
開機設定JK2410支援二種開機模
式:NAND flash開機與
NOR flash開機。
指撥開關往左為’1’,
往右為’0’。下面的指
撥為位元1,上面為位元
0,故圖的設定為
bit1=0、bit0=1,即
01。
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 10
設定 Minicom
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 11
安裝 Toolchain
# cd /# tar zxvf arm-9tdmi-linux-gnu.tar.gz(請自行修改套件來源路徑)
# export PATH=/opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-9tdmi-linux-gnu/bin/:$PATH(同一行,請勿斷行。)
(or)# source ./armpath
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 12
IP Address 設定要能順利使用TFTP協定,必須設定
JK2410的2個環境變數
– ipaddr:JK2410實驗板的IP address。
– serverip:指定TFTP server的IP address。
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 13
顯示 JK2410 環境變數jollen.org # printenvbootdelay=3ethaddr=10:10:ff:ff:ff:ffipaddr=192.168.1.10serverip=192.168.1.1netmask=255.255.255.0stdin=serialbaudrate=115200bootargs=root=/dev/ram0 rw console=ttyS0,115200 mem=64M ramdisk=16384stdout=serialstderr=serial
目前實驗板的IP address為192.168.1.10,TFTP server IP address為192.168.1.1。
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 14
修改 IP
將實驗板的IP address設定為192.168.100.15,並指定
TFTP server的IP address為192.168.100.14。
jollen.org # set ipaddr 192.168.100.15jollen.org # set serverip 192.168.100.14jollen.org # saveenvSaving Environment to Flash...Un-Protected 1 sectorsErasing Flash...Erasing sector 18 ... ok.Erased 1 sectorsWriting to Flash... doneProtected 1 sectors
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 15
利用 TFTP 下載 Kernel命令格式:
tftpboot [loadAddress] [bootfilename]
• loadAddress:儲存傳送檔案的記憶體位址(physical memory address)。
• bootfilename:TFTP server上的檔案名稱。
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 16
開機至 Linux 命令模式jollen.org # tftpboot 30F00000 uimage.imgjollen.org # tftpboot 32000000 urootfs.imgjollen.org # bootm 30F00000 32000000
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 17
取得 “Hello, World!” 範例編寫了Makefile的巨集檔進行跨平臺的
程式編譯。
下載第一個 ARM 程式範例
解開後出現 src/ 目錄。
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 18
修改路徑設定編輯src/cross.mk,將TOOL_TOP變數修改成toolchain的安裝路徑:
TOOL_TOP = /opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-9tdmi-linux-gnu
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 19
編譯程式在src/hello/目錄下執行make即可
# make[ -- Start to compile hello.c to hello.o -- ]/opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-9tdmi-linux-gnu/bin/arm-9tdmi-linux-gnu-gcc -nostdinc -I/opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-9tdmi-linux-gnu/arm-9tdmi-linux-gnu/include -I/opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-9tdmi-linux-gnu/lib/gcc/arm-9tdmi-linux-gnu/3.4.1/include -c hello.c[ -- Start to link hello.o to hello.gdb -- ]/opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-9tdmi-linux-gnu/bin/arm-9tdmi-linux-gnu-gcc -Wl,-nostdlib -Wl,-L,/opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-9tdmi-linux-gnu/arm-9tdmi-linux-gnu/lib -Wl,-L,/opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-9tdmi-linux-gnu/lib/gcc/arm-9tdmi-linux-gnu/3.4.1 -Wl,-rpath,/opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-9tdmi-linux-gnu/arm-9tdmi-linux-gnu/lib -Wl,-rpath,/lib -Wl,-rpath-link,/opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-9tdmi-linux-gnu/arm-9tdmi-linux-gnu/lib -nostartfiles -nodefaultlibs /opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-9tdmi-linux-gnu/arm-9tdmi-linux-gnu/lib/crt1.o /opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-9tdmi-linux-gnu/arm-9tdmi-linux-gnu/lib/crti.o /opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-9tdmi-linux-gnu/lib/gcc/arm-9tdmi-linux-gnu/3.4.1/crtbegin.o hello.o /opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-9tdmi-linux-gnu/lib/gcc/arm-9tdmi-linux-gnu/3.4.1/crtend.o /opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-9tdmi-linux-gnu/arm-9tdmi-linux-gnu/lib/crtn.o -lgcc -lgcc_eh -lc -lgcc -lgcc_eh -o hello.gdb[ -- Start to strip hello.gdb and produce hello -- ]/opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-9tdmi-linux-gnu/bin/arm-9tdmi-linux-gnu-strip -R .note -R .comment hello.gdb -o hello
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 20
編譯完成• hello:ELF格式的二進位執行檔,包含relocation資訊。
• hello.gdb:編譯所產生的原始執行檔,含除錯資訊(debug sections)與符號
表(symbol table)。
• hello.o:hello.c的object file。
# arm-9tdmi-linux-gnu-objdump –x hello | more(or)# readelf –a hello | more
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 21
下載至 JK2410「進入Linux作業系統」後,在Linux命
令模式下執行busybox所提供的tftp指令
下載hello至JK2410:
# tftp –g –r hello 192.168.100.14
# chmod a+x ./hello# ./hello
小提示
• hello 執行檔記得 copy 到 tftp 根目錄下 (/tftpboot in our example) 。• Target 端要記得設定 IP address (使用 ifconfig 指令)。
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 22
實例示範:Bootstrap Roofs
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 23
流程與觀念「Embedded
Linux軟體平臺」
指的是一個可供開
發人員在上面寫應
用程式的環境,在
軟體平臺建置完成
後,開發人員才能
在上面做客製化的
應用。
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 24
Cross toolchain vs native toolchain
• 我們使用native toolchain時,雖然只需要幾個簡單的參數,但其實完整的編譯參數是很亢長的,這些亢長的參數是native gcc自動加上的(即預設值)。
• 使用cross toolchain時,必須自己加上所有的參數,因為cross gcc自動加上的參數可能是GNU/Linux本身的環境,而非自己的cross toolchain環境。例如:標頭檔的路徑。
• 使用native toolchain,只需要使用gcc即可編譯出執行檔。
• 使用cross toolchain時,必須先做compiling的動作,產生object file後,再做linking。即cross compile必須分2個階段來做。
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 25
編譯“Hello, World!”
#export PATH=/opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-9tdmi-linux-gnu/bin:$PATH
#arm-9tdmi-linux-gnu-gcc -g -nostdinc \-Os -Wall -mtune=arm9tdmi -march=armv4 \-fomit-frame-pointer -fsigned-char -fPIC \-I/opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-9tdmi-linux-gnu/arm-9tdmi-linux-gnu/include \-I/opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-9tdmi-linux-gnu/lib/gcc/arm-9tdmi-linux-gnu/3.4.1/include \-c hello.c
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 26
Compiling 參數說明• -nostdinc:不使用標準路徑裡的標頭檔,也就是我們要自己指定標頭檔的搜尋路徑。
• -I:指定標頭檔(*.h)的搜尋路徑。• -mtune=arm9tdmi:指定target所使用的ARM處理器指令集架構。
• -march=armv4:指定target所使用的ARM處理器型核心架構。
• -fomit-frame-pointer:不使用frame pointer。
• -fsigned-char:使用有號的字元型別。• -fPIC:產生Position Independent Code。• -Os:對程式碼大小(size)做最佳化。• -Wall:顯示所有警告訊息。• -c:只產生object file,不呼叫ld做連結。
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 27
Linking Objects
arm-9tdmi-linux-gnu-ld \-nostdlib \-L /opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-9tdmi-linux-gnu/arm-9tdmi-linux-gnu/lib \-L /opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-9tdmi-linux-gnu/lib/gcc/arm-9tdmi-linux-gnu/3.4.1 \-rpath-link /opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-9tdmi-linux-gnu/arm-9tdmi-linux-gnu/lib \-o hello \/opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-9tdmi-linux-gnu/arm-9tdmi-linux-gnu/lib/crt1.o \/opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-9tdmi-linux-gnu/arm-9tdmi-linux-gnu/lib/crti.o \/opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-9tdmi-linux-gnu/lib/gcc/arm-9tdmi-linux-gnu/3.4.1/crtbegin.o \hello.o \/opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-9tdmi-linux-gnu/lib/gcc/arm-9tdmi-linux-gnu/3.4.1/crtend.o \/opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-9tdmi-linux-gnu/arm-9tdmi-linux-gnu/lib/crtn.o \-lgcc -lgcc_eh -lc -lgcc -lgcc_eharm-9tdmi-linux-gnu-strip -R .note -R .comment hello
編譯與連結分開做
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 28
Linking 參數• -L:指定標頭檔搜尋路徑。• -o:指定執行檔檔名。• -lc:與libc做連結。• -lgcc:與libgcc做連結。在這裡我們必須指定2個程式庫的搜尋路徑
gcc-lib的路徑:/opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-9tdmi-linux-gnu/lib/gcc/arm-9tdmi-linux-gnu/3.4.1/glibc的路徑:/opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-9tdmi-linux-gnu/arm-9tdmi-linux-gnu/lib/
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 29
觀念解說為避免cross compile的過程引用到native(x86)端的資訊與檔案,造成編譯出來的程式出現問題,因此最好將所有的參數「手動」加上去。
‘`strip’的目的在移除程式(ELF執行檔)裡的除錯節區(.debug*)與符號表格(symbol table)。’.note’與’.comment’節區也是可以移除的,因此請strip編譯好的程式。
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 30
cross.mk 重要變數定義• TOOL_TOP:Tool chain的根目錄。• GCC_LIB_PATH:gcc library的路徑。• GLIBC_PATH:glibc的路徑。• CROSS_CFLAGS:cross gcc的基本編譯參
數,指定標頭檔路徑。
• LDFLAGS:cross ld的基本連結參數,用來指定程式庫路徑。由於我們是使用gcc來呼叫ld的方式做linking,因此必須使用gcc的’-Wl’參數來傳遞linker參數。
• LIBS:要連結的基本程式庫。• LINK_S:程式所要連結的所有”start
files”。
• LINK_E:程式要所要連結的所有”end files”。
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 31
系統化的方法
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 32
移植方法說明第一種模式是本章所要介紹的移植模
式,也是最普通的open source套件移植
模式。
第二種模式適合未使用GNU autconf與
GNU automake的open source套件,
例如:busybox、Microwindows等。
第三種模式與第二種模式相似,當該套
件的Makefile撰寫是直接cross compilation時,我們便可以直接傳遞
Makefile裡的變數給make命令。
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 33
說明Madplay是一個不錯的open source
MP3撥放程式,程式簡潔精巧,相當適
合嵌入式系統使用。
準備工作 :
Cross Toolchain:自行利用
crosstool制作的ARM toolchain
– cross.mk:萬用移植巨集檔。
Base Root Filesystem:使用
Busybox製作的可開機系統。
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 34
程式庫相依問題madplay所需的shared libraries有:
libmad.so.0
libid3tag.so.0
libm.so.6
libc.so.6
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 35
找出所需的 Open Source 套件libid3tag需要zlib,由此可知,我們必須
額外移植3個套件:
libid3tag-0.15.1b.tar.gz
libmad-0.15.1b.tar.gz
zlib-1.2.1.tar.gz
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 36
Cross Compile 的順序• 移植的順序是:madplay的相依程式
庫必須先做,再回頭來移植
madplay;libid3tag相依於zlib,因此
zlib必須在libid3tag之前先做。因此這
4個套件的移植順序應為(非唯一
解):
1. libmad-0.15.1b.tar.gz2. zlib-1.2.1.tar.gz3. libid3tag-0.15.1b.tar.gz4. madplay-0.15.2b.tar.gz
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 37
移植套件的方法針對所有的open source套件,移植的做法都是一樣的:寫一個*.cross來做套件移植!
利用 cross.mk 與 GNU automake 進行 cross compilation。
優點:(1) 避免永無止境的在 key-in command (2) Makefile 的 dependency 能力很優秀 (3) 使用 script 的話,會進入永無止盡的條 件判斷式的黑洞。 (4) 共通的部份透過 cross.mk 直接引用。 (5) 透過 GNU automake 來建構自動化的 “build system”。
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 38
先做 libmad 移植1. 將libmad-0.15.1b.tar.gz解開,並複製
cross.mk至libmad-0.15.1b/目錄裡。
2. 撰寫libmad專用的cross檔如下,請命
名為libmad.cross,並存放於libmad-0.15.1b/目錄裡。
3. 執行’make’以編譯程式。
4. 完成libmad的移植!請執行’make
install’安裝libmad的shared libraries
與header files到toolchain的glibc程式
庫目錄下。
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 39
原理說明執行./configure的目的是為了產生Makefile,因此移植的原理是「控制./configure產生一個可供cross compile的Makefile」。
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 40
方法方法如下:
Toolchain必須全部改用ARM
toolchain
必須完整指定編譯(compile)參
數:使用前面所設計的cross.mk檔。
必須完整指定鍊結(linking)參數:
使用前面所設計的cross.mk檔。
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 41
設定 configure 環境變數• configure會讀取以下幾個環境變數來產生Makfile檔,因此在執行configure前,必須正確設定這幾個環境變數:
– CC:定義ARM toolchain提供的gcc路徑與執行檔名稱。
– AR:定義ARM toolchain提供的ar路徑與執行檔名稱。
– LD:定義ARM toolchain提供的ld路徑與執行檔名稱。
– AS:定義ARM toolchain提供的as路徑與執行檔名稱。
– STRIP:定義ARM toolchain提供的strip路徑與執行檔名稱。
– RANLIB:定義ARM toolchain提供ranlib路徑與執行檔名稱。
– CFLAGS:定義ARM cross gcc的編譯參數。
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 42
必備參數• configure的設定參數中,有2個參數是在做cross compilation時,必須加上去的:
– --prefix:指定安裝套件的路徑。若是程式庫,則指定為「cross toolchain 的glibc目錄」,並在編
譯完成後執行’make install’進行安裝;若是一
般應用程式,請指定為’/’,在編譯完成後,請
「不要」執行’make install’命令,應手動安裝
應用程式至root filesystem目錄下。
– --host:指定target device的平臺,請指定為’arm-linux’。
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 43
Madplay Project 的 Software Stack
libmad libid3tagzlib
Madplay
Building root filesystem (porting) 的主要觀念:• standalone application (e.g. thttpd)• software stacks (e.g. madplay project)• software stacks with architectural consideration
(e.g. nano-X project)
這是一個單純的堆疊關係
Kernel 編譯與除錯簡介
44
Text
http://www.pconline.com.cn/pcedu/soft/gj/sys/0502/551643.html
Definition of a Software "bug":
Webster's New Collegiate Dictionary defines a "bug" as "an unexpected defect, fault, flaw, or imperfection". We need to refine this definition since it is too ambiguous. In the scope of this guarantee, a "bug", with respect to the guaranteed software, is defined as "a defect, fault, flaw or imperfection which causes the software to not operate as intended or to stop operating abruptly."
http://www.autocadstandards.org/autocadstandards/bugfree/default.htm
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting
Debug Techniques
User-space Debugging
Breakpoint, single step, inspect variables
Segmentation fault
Core dump
Multi-thread, client-server, GUI
Kernel-space Debugging
Boot-timeSystem Call
Exceptions
47
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting
基本除錯工具
gdb, http://www.gnu.org/software/gdb/
cgdb, http://cgdb.sourceforge.net/
ddd, http://www.gnu.org/software/ddd/
kgdb, http://kgdb.linsyssoft.com/
kdb, http://oss.sgi.com/projects/kdb/
48
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting
基本 kernel debug 工具
printk
kdb
kgdb
kgdb light (linux >= 2.6.26)
gdb + qemu
oops (kernel panic)
49
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting
kernel debug 比較
使用難度 除錯強度
printk 易 低
kdb 中 中
kgdb 中 高
gdb + qemu 中 高
50
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting
kernel debug 模式
debug 模式 讀取符號表
printk remote debug N
kdb local debug N
kgdb remote debug Y
gdb + qemu remote debug Y
51
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting
Remote Debug
Linux kernel image
• arch/arm/boot/Image
• arch/arm/boot/zImage
• arch/arm/boot/uImage
載入 target 端的 kernel
• ./vmlinux ELF image、用來載入符號表
52
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting
Debug-Level
source level 編譯注意事項
printk kernel message --
kdb machine code --
gdb + qemu source code kernel w/ symbol table
kgdb source code kernel w/ symbol table
53
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting
gdb w/ qemu
讀取 qemu 的 register set
Qemu 實作的 gdb server
gdb client 以 socket 連接 Qemu gdb server
54
加入 Debug Symbols
CONFIG_DEBUG_INFO = y
linux kernel for s3c2410
http://www.jk2410.org/opensource/linux-2.6.20.4-jk2410.tar.bz2
$ make ARCH=arm CROSS_COMPILE=/opt/crosstool/gcc-4.1.0-glibc-2.4/arm-9tdmi-linux-gnueabi/bin/
arm-9tdmi-linux-gnueabi- menuconfig
$ make ARCH=arm CROSS_COMPILE=/opt/crosstool/gcc-4.1.0-glibc-2.4/arm-9tdmi-linux-gnueabi/bin/
arm-9tdmi-linux-gnueabi- uImage
http://www.jk2410.org/opensource/gcc-4.1.0-glibc-2.4.tar.bz2
$ make uImage
$ cd /usr/local/bin$ sudo wget http://www.jk2410.org/opensource/pre-built/mkimage$ chmod a+x mkimage
http://www.jk2410.org/opensource/qemu-jk2410-20070826.tar.gz
執行 qemu、啟動新修改並編譯好的 kernel
1、執行 cgdb 進行除錯
2、連到 qemu
1、先設定中斷點
2、再將 kernel 啟動
kernel 停在預先設立的中斷點
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting
其它除錯技議題oops message
System.map
/proc/ksyms
vmlinux
/proc/modules
技巧較多
62
U-Boot 簡介
63
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 64
U-Boot 程式邏輯結構
CPU 初始化
Board 初始化
main_loop(): main.c
• Setup vector table • Set the CPU to SVC32 mode (reset)• Relocate to RAM• Setup stack
cpu/arm920t/start.S
board/lart/memsetup.Slib_arm/board.c
• Board initialize sequence• start_armboot()• Call main_loop()
board/<board>/*, eg.board/lart/lart.c
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 65
Setup vector table.globl _start_start: b reset ldr pc, _undefined_instruction ldr pc, _software_interrupt ldr pc, _prefetch_abort ldr pc, _data_abort ldr pc, _not_used ldr pc, _irq ldr pc, _fiq
_undefined_instruction: .word undefined_instruction_software_interrupt: .word software_interrupt_prefetch_abort: .word prefetch_abort_data_abort: .word data_abort_not_used: .word not_used_irq: .word irq_fiq: .word fiq
.balignl 16,0xdeadbeef
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 66
reset/* * the actual reset code */
reset: /* * set the cpu to SVC32 mode */ mrs r0,cpsr bic r0,r0,#0x1f orr r0,r0,#0xd3 msr cpsr,r0...#ifdef CONFIG_INIT_CRITICAL bl cpu_init_crit#endif
Where memsetup be called.
relocate
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 67
cpu_init_crit
cpu_init_crit: /* * flush v4 I/D caches */ mov r0, #0 mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
/* * disable MMU stuff and caches */ mrc p15, 0, r0, c1, c0, 0 bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM) orr r0, r0, #0x00000002 @ set bit 2 (A) Align orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache mcr p15, 0, r0, c1, c0, 0
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 68
cpu_init_crit
/* * before relocating, we have to setup RAM timing * because memory timing is board-dependend, you will * find a memsetup.S in your board directory. */ mov ip, lr bl memsetup mov lr, ip
mov pc, lr
Return to reset.board/lart/memsetup.S
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 69
memsetupEM_BASE: .long 0xa0000000MEM_START: .long 0xc0000000
#define MDCNFG 0x00#define MDCAS0 0x04#define MDCAS1 0x08#define MDCAS2 0x0c#define MSC0 0x10#define MSC1 0x14#define MECR 0x18
mdcas0: .long 0xc71c703fmdcas1: .long 0xffc71c71mdcas2: .long 0xffffffff/* mdcnfg: .long 0x0bb2bcbf */mdcnfg: .long 0x0334b22f @ alt/* mcs0: .long 0xfff8fff8 */msc0: .long 0xad8c4888 @ altmecr: .long 0x00060006/* mecr: .long 0x994a994a @ alt */
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 70
memsetup.globl memsetupmemsetup: ldr r0, MEM_BASE
/* Setup the flash memory */ ldr r1, msc0 str r1, [r0, #MSC0]
/* Set up the DRAM */
/* MDCAS0 */ ldr r1, mdcas0 str r1, [r0, #MDCAS0]
/* MDCAS1 */ ldr r1, mdcas1 str r1, [r0, #MDCAS1]
/* MDCAS2 */ ldr r1, mdcas2 str r1, [r0, #MDCAS2]
/* MDCNFG */ ldr r1, mdcnfg str r1, [r0, #MDCNFG]
/* Set up PCMCIA space */ ldr r1, mecr str r1, [r0, #MECR]
/* Load something to activate bank */ ldr r1, MEM_START
.rept 8 ldr r0, [r1].endr
/* everything is fine now */ mov pc, lr
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 71
Relocation to RAMrelocate: /* relocate U-Boot to RAM */ adr r0, _start /* r0 <- current position of code */ ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ cmp r0, r1 /* don't reloc during debug */ beq stack_setup
ldr r2, _armboot_start ldr r3, _bss_start sub r2, r3, r2 /* r2 <- size of armboot */ add r2, r0, r2 /* r2 <- source end address */
copy_loop: ldmia r0!, {r3-r10} /* copy from source address [r0] */ stmia r1!, {r3-r10} /* copy to target address [r1] */ cmp r0, r2 /* until source end addreee [r2] */ ble copy_loop
stack_setup
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 72
Setup stack /* Set up the stack */stack_setup: ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ sub r0, r0, #CFG_MALLOC_LEN /* malloc area */ sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */#ifdef CONFIG_USE_IRQ sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)#endif sub sp, r0, #12 /* leave 3 words for abort-stack */
clear_bss
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 73
Setup stack
ldr pc, _start_armboot
_start_armboot: .word start_armboot
clear_bss: ldr r0, _bss_start /* find start of bss segment */ add r0, r0, #4 /* start at first byte of bss */ ldr r1, _bss_end /* stop here */ mov r2, #0x00000000 /* clear */
clbss_l:str r2, [r0] /* clear loop... */ add r0, r0, #4 cmp r0, r1 bne clbss_l...
lib_arm/board.c
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 74
start_armboot()typedef int (init_fnc_t) (void);
init_fnc_t *init_sequence[] = { cpu_init, /* basic cpu dependent setup */ board_init, /* basic board dependent setup */ interrupt_init, /* set up exceptions */ env_init, /* initialize environment */ init_baudrate, /* initialze baudrate settings */ serial_init, /* serial communications setup */ console_init_f, /* stage 1 init of console */ display_banner, /* say that we are here */ dram_init, /* configure available RAM banks */ display_dram_config, NULL,};
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 75
start_armboot()
void start_armboot (void){ init_fnc_t **init_fnc_ptr;
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { if ((*init_fnc_ptr)() != 0) { hang (); } } . . . /* main_loop() can return to retry autoboot, if so just run it again. */ for (;;) { main_loop (); } }
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 76
Pseudo Code for Booting ARM Linuxvoid start_linux(char *name,char *rdname){ void (*theKernel)(int zero, int arch, u32 params); u32 exec_at = ZIMAGE_LOAD_ADDRESS; u32 parm_at = DRAM_BASE + 0x100; u32 machine_type;
load_image(name, exec_at); /* copy image into RAM */ load_image(rdname, INITRD_LOAD_ADDRESS);/* copy initial ramdisk image into RAM */ setup_tags(parm_at); /* sets up parameters */ machine_type = get_mach_type(); /* get machine type */ irq_shutdown(); /* stop irq */ cpu_op(CPUOP_MMUCHANGE, NULL); /* turn MMU off */ theKernel = (void (*)(int, int, u32))exec_at; /* set the kernel address */ theKernel(0, machine_type, parm_at); /* jump to kernel with register set */
/* NOT REACHED */}
Linux Device Drivers 實作簡介
77
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 78
Linux Device Driver Architecture
System Call Interface
Virture File System(VFS)
Buffer Cache
Application
CharacterDevice Driver
Physical Device (Hardware)
Network Subsystem
Device Interface
Kernel Mode
User Mode
Hardware
BlockDevice Driver
Network Device Driver
BSD socket
inet(AF_INET)
Transport(TCP,UDP)
Network(IP)
Source: Jollen 的 Linux 驅動程式講義 (Revision 5)
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 79
Device Registration and ReleaseRegistration
Release
int register_chrdev(unsigned int major, const char * name, struct file_operations *fops)
int unregister_chrdev(unsigned int major, const char * name)
int register_blkdev(unsigned int major, const char *name, struct file_operations *fops)
int unregister_blkdev(unsigned int major, const char *name)
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 80
Data Structure of Linux Device Driverstruct file_operations { /* character device drivers */
struct module *owner;
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char *, size_t, loff_t *);
int (*readdir) (struct file *, void *, filldir_t);
unsigned int (*poll) (struct file *, struct poll_table_struct *);
int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
int (*open) (struct inode *, struct file *);
int (*flush) (struct file *);
int (*release) (struct inode *, struct file *);
int (*fsync) (struct file *, struct dentry *, int datasync);
int (*fasync) (int, struct file *, int);
int (*lock) (struct file *, int, struct file_lock *);
ssize_t (*readv) (struct file *, const struct iovec *, unsigned long, loff_t *);
ssize_t (*writev) (struct file *, const struct iovec *, unsigned long, loff_t *);
ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long,
unsigned long, unsigned long);
};
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 81
Registration Example#define MSG(m...) printk(KERN_INFO "DEBUG CARD: " m "\n")
#define DEV_MAJOR 121#define DEV_NAME "debug"
struct file_operations card_fops = {};
int init_module(void){ MSG("DEBUG CARD v0.1.0"); MSG(" Copyright (C) 2004 www.jollen.org");
if (register_chrdev(DEV_MAJOR, DEV_NAME, &card_fops) < 0) { MSG("Couldn't register a device."); return -1; } return 0;}
Source: Jollen 的 Linux 驅動程式講義 (Revision 5)
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting
將 cdata 整合到 Kernel題目:將自已的 cdata 驅動程式整合到 kernel:
可透過 make menuconfig 選取
編譯 cdata 到 kernel 裡
目的:
大略了解 kernel source tree 結構
學會將 driver 整合到 Linux kernel
82
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting
實作中斷處理題目:修改 JK2410 kernel 的 cdata 驅動程式:
加入 JK2410 的 GPIO button driver
寫一個程式,當 user 按下 S5 時,撥放音樂。
目的:
學會寫 interrupt handler
了解 bottom-half 的觀念
觀察中斷線 (IRQ) 的運作原理
學會 tasklet 的使用時機83
《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting
其他議題驅動程式設計
multi-thread 的議題
重覆進入函數
同步控制
kernel scheduling
more
驅動程式實作
Subsystem的使用
more
84
陳俊宏 Jollen Chen <[email protected]>
Jollen's Consulting主持人,有豐富的Embedded Linux顧問與授課經驗,致力於專業課程的開發、以及建立教育訓練的價值。 陳俊宏先生過去任職知名的開放手機公
司Openmoko,負責規劃與執行Openmoko在大中華區的行銷與推廣工作,在這二年
的時間裡,他帶領Openmoko團隊進行技術行銷,並深耕台灣的教育市場,對開放手機平臺的技術推廣不遺餘力。 陳俊宏先生目前專注於Android OS底層的技術研究,以
及Android驅動程式的開發,並且為大陸地區業界提供Android培訓課程。
目前亦為北京中關村開放手機聯盟-共同發起人、目前參與多項Android研發計設。
目前專注於Android porting (s3c244x/s3c64x0)、Linux驅動開發、嵌入式Linux架構設計、底層技術導入與顧問等工作。Jollen的部落格- www.jollen.org/blog
www.jollen.org/consulting