Top Banner
嵌入式Linux系統簡介 u-boot,kernel,drvier,rootfs操作示範
85

Embedded Linux: Introduction

May 10, 2015

Download

Education

Jollen Chen

嵌入式Linux簡介
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Embedded Linux: Introduction

嵌入式Linux系統簡介

u-boot,kernel,drvier,rootfs操作示範

Page 2: Embedded Linux: Introduction

Jollen’s Consulting

與優質的課程平臺商合作, 專注課程研究與開發,致力創造教育訓練的價值

課程供應與開發者,致力於價值創造詳細資訊: www.jollen.org/consulting

專業課程供應

Page 3: Embedded Linux: Introduction

歡迎參加由 Jollen’s Consulting 所規劃與主講的課程,參加我們任何課程,您皆可透過 [email protected] 信箱登錄個人資料,即可加入郵件列表;郵件主旨請填寫 [加入郵件列表]、郵件內文空白即可

我們將不定時提供以下資訊:

公開的講義電子檔 題庫系統使用帳號 實作測試題目(提供學員練功題目)

Jollen’s Consulting Team

Page 4: Embedded Linux: Introduction

嵌入式 Linux 系統簡介

Jollen Chen (陳俊宏)

Email:[email protected]

Blog:jollen.org/blog

課程時間:2009.09.15

主辦單位:佳士達.Jollen’s Consulting

Page 5: Embedded Linux: Introduction

《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting

授課計畫

課程主旨:

針對Embedded Linux系統所涉及的實作進行簡介

課程主題:

Cross Toolchain & Root Filesystem 簡介

Kernel 編譯與除錯簡介

U-Boot 簡介

Linux Device Drivers 實作簡介

5

Page 6: Embedded Linux: Introduction

Cross Toolchain & Root Filesystem 簡介

6

Page 7: Embedded Linux: Introduction

《嵌入式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。

Page 8: Embedded Linux: Introduction

《嵌入式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組。

Page 9: Embedded Linux: Introduction

《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 9

開機設定JK2410支援二種開機模

式:NAND flash開機與

NOR flash開機。

指撥開關往左為’1’,

往右為’0’。下面的指

撥為位元1,上面為位元

0,故圖的設定為

bit1=0、bit0=1,即

01。

Page 10: Embedded Linux: Introduction

《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 10

設定 Minicom

Page 11: Embedded Linux: Introduction

《嵌入式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

Page 12: Embedded Linux: Introduction

《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 12

IP Address 設定要能順利使用TFTP協定,必須設定

JK2410的2個環境變數

– ipaddr:JK2410實驗板的IP address。

– serverip:指定TFTP server的IP address。

Page 13: Embedded Linux: Introduction

《嵌入式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。

Page 14: Embedded Linux: Introduction

《嵌入式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

Page 15: Embedded Linux: Introduction

《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 15

利用 TFTP 下載 Kernel命令格式:

tftpboot [loadAddress] [bootfilename]

• loadAddress:儲存傳送檔案的記憶體位址(physical memory address)。

• bootfilename:TFTP server上的檔案名稱。

Page 16: Embedded Linux: Introduction

《嵌入式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

Page 17: Embedded Linux: Introduction

《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 17

取得 “Hello, World!” 範例編寫了Makefile的巨集檔進行跨平臺的

程式編譯。

下載第一個 ARM 程式範例

解開後出現 src/ 目錄。

Page 18: Embedded Linux: Introduction

《嵌入式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

Page 19: Embedded Linux: Introduction

《嵌入式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

Page 20: Embedded Linux: Introduction

《嵌入式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

Page 21: Embedded Linux: Introduction

《嵌入式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 指令)。

Page 22: Embedded Linux: Introduction

《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 22

實例示範:Bootstrap Roofs

Page 23: Embedded Linux: Introduction

《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 23

流程與觀念「Embedded

Linux軟體平臺」

指的是一個可供開

發人員在上面寫應

用程式的環境,在

軟體平臺建置完成

後,開發人員才能

在上面做客製化的

應用。

Page 24: Embedded Linux: Introduction

《嵌入式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個階段來做。

Page 25: Embedded Linux: Introduction

《嵌入式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

Page 26: Embedded Linux: Introduction

《嵌入式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做連結。

Page 27: Embedded Linux: Introduction

《嵌入式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

編譯與連結分開做

Page 28: Embedded Linux: Introduction

《嵌入式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/

Page 29: Embedded Linux: Introduction

《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 29

觀念解說為避免cross compile的過程引用到native(x86)端的資訊與檔案,造成編譯出來的程式出現問題,因此最好將所有的參數「手動」加上去。

‘`strip’的目的在移除程式(ELF執行檔)裡的除錯節區(.debug*)與符號表格(symbol table)。’.note’與’.comment’節區也是可以移除的,因此請strip編譯好的程式。

Page 30: Embedded Linux: Introduction

《嵌入式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”。

Page 31: Embedded Linux: Introduction

《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 31

系統化的方法

Page 32: Embedded Linux: Introduction

《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 32

移植方法說明第一種模式是本章所要介紹的移植模

式,也是最普通的open source套件移植

模式。

第二種模式適合未使用GNU autconf與

GNU automake的open source套件,

例如:busybox、Microwindows等。

第三種模式與第二種模式相似,當該套

件的Makefile撰寫是直接cross compilation時,我們便可以直接傳遞

Makefile裡的變數給make命令。

Page 33: Embedded Linux: Introduction

《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 33

說明Madplay是一個不錯的open source

MP3撥放程式,程式簡潔精巧,相當適

合嵌入式系統使用。

準備工作 :

Cross Toolchain:自行利用

crosstool制作的ARM toolchain

– cross.mk:萬用移植巨集檔。

Base Root Filesystem:使用

Busybox製作的可開機系統。

Page 34: Embedded Linux: Introduction

《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 34

程式庫相依問題madplay所需的shared libraries有:

libmad.so.0

libid3tag.so.0

libm.so.6

libc.so.6

Page 35: Embedded Linux: Introduction

《嵌入式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

Page 36: Embedded Linux: Introduction

《嵌入式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

Page 37: Embedded Linux: Introduction

《嵌入式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”。

Page 38: Embedded Linux: Introduction

《嵌入式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程式

庫目錄下。

Page 39: Embedded Linux: Introduction

《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 39

原理說明執行./configure的目的是為了產生Makefile,因此移植的原理是「控制./configure產生一個可供cross compile的Makefile」。

Page 40: Embedded Linux: Introduction

《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting 40

方法方法如下:

Toolchain必須全部改用ARM

toolchain

必須完整指定編譯(compile)參

數:使用前面所設計的cross.mk檔。

必須完整指定鍊結(linking)參數:

使用前面所設計的cross.mk檔。

Page 41: Embedded Linux: Introduction

《嵌入式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的編譯參數。

Page 42: Embedded Linux: Introduction

《嵌入式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’。

Page 43: Embedded Linux: Introduction

《嵌入式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)

這是一個單純的堆疊關係

Page 44: Embedded Linux: Introduction

Kernel 編譯與除錯簡介

44

Page 46: Embedded Linux: Introduction

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

Page 47: Embedded Linux: Introduction

《嵌入式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

Page 48: Embedded Linux: Introduction

《嵌入式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

Page 49: Embedded Linux: Introduction

《嵌入式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

Page 50: Embedded Linux: Introduction

《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting

kernel debug 比較

使用難度 除錯強度

printk 易 低

kdb 中 中

kgdb 中 高

gdb + qemu 中 高

50

Page 51: Embedded Linux: Introduction

《嵌入式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

Page 52: Embedded Linux: Introduction

《嵌入式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

Page 53: Embedded Linux: Introduction

《嵌入式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

Page 54: Embedded Linux: Introduction

《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting

gdb w/ qemu

讀取 qemu 的 register set

Qemu 實作的 gdb server

gdb client 以 socket 連接 Qemu gdb server

54

Page 55: Embedded Linux: Introduction

加入 Debug Symbols

CONFIG_DEBUG_INFO = y

Page 56: Embedded Linux: Introduction

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

Page 57: Embedded Linux: Introduction

$ make uImage

$ cd /usr/local/bin$ sudo wget http://www.jk2410.org/opensource/pre-built/mkimage$ chmod a+x mkimage

Page 58: Embedded Linux: Introduction

http://www.jk2410.org/opensource/qemu-jk2410-20070826.tar.gz

執行 qemu、啟動新修改並編譯好的 kernel

Page 59: Embedded Linux: Introduction

1、執行 cgdb 進行除錯

2、連到 qemu

Page 60: Embedded Linux: Introduction

1、先設定中斷點

2、再將 kernel 啟動

Page 61: Embedded Linux: Introduction

kernel 停在預先設立的中斷點

Page 62: Embedded Linux: Introduction

《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting

其它除錯技議題oops message

System.map

/proc/ksyms

vmlinux

/proc/modules

技巧較多

62

Page 63: Embedded Linux: Introduction

U-Boot 簡介

63

Page 64: Embedded Linux: Introduction

《嵌入式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

Page 65: Embedded Linux: Introduction

《嵌入式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

Page 66: Embedded Linux: Introduction

《嵌入式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

Page 67: Embedded Linux: Introduction

《嵌入式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

Page 68: Embedded Linux: Introduction

《嵌入式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

Page 69: Embedded Linux: Introduction

《嵌入式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 */

Page 70: Embedded Linux: Introduction

《嵌入式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

Page 71: Embedded Linux: Introduction

《嵌入式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

Page 72: Embedded Linux: Introduction

《嵌入式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

Page 73: Embedded Linux: Introduction

《嵌入式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

Page 74: Embedded Linux: Introduction

《嵌入式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,};

Page 75: Embedded Linux: Introduction

《嵌入式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 (); } }

Page 76: Embedded Linux: Introduction

《嵌入式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 */}

Page 77: Embedded Linux: Introduction

Linux Device Drivers 實作簡介

77

Page 78: Embedded Linux: Introduction

《嵌入式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)

Page 79: Embedded Linux: Introduction

《嵌入式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)

Page 80: Embedded Linux: Introduction

《嵌入式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);

};

Page 81: Embedded Linux: Introduction

《嵌入式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)

Page 82: Embedded Linux: Introduction

《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting

將 cdata 整合到 Kernel題目:將自已的 cdata 驅動程式整合到 kernel:

可透過 make menuconfig 選取

編譯 cdata 到 kernel 裡

目的:

大略了解 kernel source tree 結構

學會將 driver 整合到 Linux kernel

82

Page 83: Embedded Linux: Introduction

《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting

實作中斷處理題目:修改 JK2410 kernel 的 cdata 驅動程式:

加入 JK2410 的 GPIO button driver

寫一個程式,當 user 按下 S5 時,撥放音樂。

目的:

學會寫 interrupt handler

了解 bottom-half 的觀念

觀察中斷線 (IRQ) 的運作原理

學會 tasklet 的使用時機83

Page 84: Embedded Linux: Introduction

《嵌入式Linux系統:簡介與實例示範-佳士達內訓》課程規劃.教材提供:Jollen’s Consulting. www.jollen.org/consulting

其他議題驅動程式設計

multi-thread 的議題

重覆進入函數

同步控制

kernel scheduling

more

驅動程式實作

Subsystem的使用

more

84

Page 85: Embedded Linux: Introduction

陳俊宏 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