PIXNET Logo登入

立你斯學習記錄

跳到主文

歡迎光臨 立你斯 在痞客邦的小天地..這裡主要轉貼我工作上有遇過的問題或看過的查過的資料....盡量轉成正體..留存

部落格全站分類:數位生活

  • 相簿
  • 部落格
  • 留言
  • 名片
  • 4月 26 週四 200700:35
  • LINUX make menuconfig 語法


===介紹
 
有4 個不同的configuration programs 是使用 Config Language︰
 
(繼續閱讀...)
文章標籤

立你斯 發表在 痞客邦 留言(0) 人氣(9,357)

  • 個人分類:編譯相關
▲top
  • 4月 26 週四 200700:33
  • LINUX 驅動程式 LDD3

LINUX 驅動程式 LDD3
  http://www.21cstar.com/dhome/uploadfile/ldd3_html/index.html
簡體版本
目錄

1. 第一章 設備驅動簡介


1.1. 驅動程式的角色
1.2. 劃分核心


1.2.1. 可加載模組

1.3. 設備和模組的分類
1.4. 安全問題
1.5. 版本編號
1.6. 版權條款
1.7. 加入核心開發社團
1.8. 本書的內容
2. 建立和執行模組


2.1. 設定你的測試系統
2.2. Hello World 模組
2.3. 核心模組相比於應用程式


2.3.1. 用戶空間和核心空間
2.3.2. 核心的並發
2.3.3. 當前進程
2.3.4. 幾個別的細節
2.4. 編譯和加載


2.4.1. 編譯模組
2.4.2. 加載和卸載模組
2.4.3. 版本倚賴
2.4.4. 平台倚賴性
2.5. 核心符號表
2.6. 預備知識
2.7. 初始化和關停


2.7.1. 清理函數
2.7.2. 初始化中的錯誤處理
2.7.3. 模組加載競爭
2.8. 模組參數
2.9. 在用戶空間做
2.10. 快速參考
3. 字元驅動


3.1. scull 的設計
3.2. 主次編號


3.2.1. 設備編號的內部表示
3.2.2. 分發和釋放設備編號
3.2.3. 主編號的動態分發
3.3. 一些重要數據架構


3.3.1. 檔案操作
3.3.2. 檔案架構
3.3.3. inode 架構
3.4. 字元設備註冊


3.4.1. scull 中的設備註冊
3.4.2. 老方法
3.5. open 和 release


3.5.1. open 方法
3.5.2. release 方法
3.6. scull 的記憶體使用
3.7. 讀和寫


3.7.1. read 方法
3.7.2. write 方法
3.7.3. readv 和 writev
3.8. 使用新設備
3.9. 快速參考
4. 調試技術


4.1. 核心中的調試支援
4.2. 用列印調試


4.2.1. printk
4.2.2. 重定向控制台消息
4.2.3. 消息是如何記錄的
4.2.4. 打開和關閉消息
4.2.5. 速率限制
4.2.6. 列印設備編號
4.3. 用查詢來調試


4.3.1. 使用 /proc 檔案系統
4.3.2. ioctl 方法
4.4. 使用觀察來調試
4.5. 調試系統故障


4.5.1. oops 消息
4.5.2. 系統掛起
4.6. 調試器和相關工具


4.6.1. 使用 gdb
4.6.2. kdb 核心調試器
4.6.3. kgdb 補丁
4.6.4. 用戶模式 Linux 移植
4.6.5. Linux 追蹤工具
4.6.6. 動態探針
5. 並發和競爭情況


5.1. scull 中的缺陷
5.2. 並發和它的管理
5.3. 旗標和互斥體


5.3.1. Linux 旗標實現
5.3.2. 在 scull 中使用旗標
5.3.3. 讀者/寫者旗標
5.4. Completions 機制
5.5. 自旋鎖


5.5.1. 自旋鎖 API 簡介
5.5.2. 自旋鎖和原子上下文
5.5.3. 自旋鎖函數
5.5.4. 讀者/寫者自旋鎖
5.6. 鎖陷阱


5.6.1. 模糊的規則
5.6.2. 加鎖順序規則
5.6.3. 細 -粗- 粒度加鎖
5.7. 加鎖的各種選擇


5.7.1. 不加鎖算法
5.7.2. 原子變量
5.7.3. 位操作
5.7.4. seqlock 鎖
5.7.5. 讀取-拷貝-更新
5.8. 快速參考
6. 進階字元驅動操作


6.1. ioctl 界面


6.1.1. 選擇 ioctl 命令
6.1.2. 返回值
6.1.3. 預定義的命令
6.1.4. 使用 ioctl 參數
6.1.5. 兼容性和受限操作
6.1.6. ioctl 命令的實現
6.1.7. 不用 ioctl 的設備控制
6.2. 阻塞 I/O


6.2.1. 睡眠的介紹
6.2.2. 簡單睡眠
6.2.3. 阻塞和非阻塞操作
6.2.4. 一個阻塞 I/O 的例子
6.2.5. 進階睡眠
6.2.6. 測試 scullpipe 驅動
6.3. poll 和 select


6.3.1. 與 read 和 write 的交互
6.3.2. 底層的數據架構
6.4. 異步通知


6.4.1. 驅動的觀點

6.5. 移位一個設備


6.5.1. llseek 實現

6.6. 在一個設備檔案上的存取控制


6.6.1. 單 open 設備
6.6.2. 一次對一個用戶限制存取
6.6.3. 阻塞 open 作為對 EBUSY 的替代
6.6.4. 在 open 時複製設備
6.7. 快速參考
7. 時間, 延時, 和延後工作


7.1. 測量時間流失


7.1.1. 使用 jiffies 計數器
7.1.2. 處理器特定的暫存器
7.2. 獲知當前時間
7.3. 延後執行


7.3.1. 長延時
7.3.2. 短延時
7.4. 核心定時器


7.4.1. 定時器 API
7.4.2. 核心定時器的實現
7.5. Tasklets 機制
7.6. 工作隊列


7.6.1. 共享隊列

7.7. 快速參考


7.7.1. 時間管理
7.7.2. 延遲
7.7.3. 核心定時器
7.7.4. Tasklets 機制
7.7.5. 工作隊列
8. 分發記憶體


8.1. kmalloc 的真實故事


8.1.1. flags 參數
8.1.2. size 參數
8.2. 後備緩存


8.2.1. 一個基於 Slab 緩存的 scull: scullc
8.2.2. 記憶體池
8.3. get_free_page 和其友


8.3.1. 一個使用整頁的 scull: scullp
8.3.2. alloc_pages 界面
8.3.3. vmalloc 和 其友
8.3.4. 一個使用虛擬位址的 scull : scullv
8.4. 每-CPU 的變量
8.5. 獲得大量緩衝


8.5.1. 在啟動時獲得專用的緩衝

8.6. 快速參考
9. 與硬體通訊


9.1. I/O 端口和 I/O 記憶體


9.1.1. I/O 暫存器和常規記憶體

9.2. 使用 I/O 端口


9.2.1. I/O 端口分發
9.2.2. 操作 I/O 端口
9.2.3. 從用戶空間的 I/O 存取
9.2.4. 字串操作
9.2.5. 暫停 I/O
9.2.6. 平台倚賴性
9.3. 一個 I/O 端口例子


9.3.1. 並口縱覽
9.3.2. 一個例子驅動
9.4. 使用 I/O 記憶體


9.4.1. I/O 記憶體分發和映射
9.4.2. 存取 I/O 記憶體
9.4.3. 作為 I/O 記憶體的端口
9.4.4. 重用 short 為 I/O 記憶體
9.4.5. 在 1 MB 之下的 ISA 記憶體
9.4.6. isa_readb 和其友
9.5. 快速參考
10. 中斷處理


10.1. 準備並口
10.2. 安裝一個中斷處理


10.2.1. /proc 界面
10.2.2. 自動檢測 IRQ 號
10.2.3. 快速和慢速處理
10.2.4. 實現一個處理
10.2.5. 處理者的參數和返回值
10.2.6. 使能和禁止中斷
10.3. 前和後半部


10.3.1. Tasklet 實現
10.3.2. 工作隊列
10.4. 中斷共享


10.4.1. 安裝一個共享的處理者
10.4.2. 執行處理者
10.4.3. /proc 界面和共享中斷
10.5. 中斷驅動 I/O


10.5.1. 一個寫緩存例子

10.6. 快速參考
11. 核心中的數據類型


11.1. 標準 C 類型的使用
11.2. 安排一個明確大小給數據項
11.3. 界面特定的類型
11.4. 其他移植性問題


11.4.1. 時間間隔
11.4.2. 頁大小
11.4.3. 位元組序
11.4.4. 數據對齊
11.4.5. 指標和錯誤值
11.5. 連結表
11.6. 快速參考
12. PCI 驅動


12.1. PCI 界面


12.1.1. PCI 尋址
12.1.2. 啟動時間
12.1.3. 配置暫存器和初始化
12.1.4. MODULEDEVICETABLE巨集
12.1.5. 註冊一個 PCI 驅動
12.1.6. 老式 PCI 探測
12.1.7. 使能 PCI 設備
12.1.8. 存取配置空間
12.1.9. 存取 I/O 和記憶體空間
12.1.10. PCI 中斷
12.1.11. 硬體抽象
12.2. 回顧: ISA


12.2.1. 硬體資源
12.2.2. ISA 編程
12.2.3. 即插即用規範
12.3. PC/104 和 PC/104+
12.4. 其他的 PC 匯流排


12.4.1. MCA 匯流排
12.4.2. EISA 匯流排
12.4.3. VLB 匯流排
12.5. SBus
12.6. NuBus 匯流排
12.7. 外部匯流排
12.8. 快速參考
13. USB 驅動


13.1. USB 設備基礎知識


13.1.1. 端點
13.1.2. 界面
13.1.3. 配置
13.2. USB 和 sysfs
13.3. USB 的 Urbs


13.3.1. 架構 struct urb
13.3.2. 建立和銷毀 urb
13.3.3. 提交 urb
13.3.4. 完成 urb: 完成回調處理者
13.3.5. 取消 urb
13.4. 編寫一個 USB 驅動


13.4.1. 驅動支援什麼設備
13.4.2. 註冊一個 USB 驅動
13.4.3. 提交和控制一個 urb
13.5. 無 urb 的 USB 傳送


13.5.1. usb_bulk_msg 界面
13.5.2. usb_control_msg 界面
13.5.3. 使用 USB 數據函數
13.6. 快速參考
14. Linux 設備模型


14.1. Kobjects, Ksets 和 Subsystems


14.1.1. Kobject 基礎
14.1.2. kobject 層次, kset, 和子系統
14.2. 低級 sysfs 操作


14.2.1. 預設屬性
14.2.2. 非預設屬性
14.2.3. 二進製屬性
14.2.4. 符號連接
14.3. 熱插拔事件產生


14.3.1. 熱插拔操作

14.4. 匯流排, 設備, 和驅動


14.4.1. 匯流排
14.4.2. 設備
14.4.3. 設備驅動
14.5. 類


14.5.1. class_simple 界面
14.5.2. 完整的類界面
14.6. 集成起來


14.6.1. 添加一個設備
14.6.2. 去除一個設備
14.6.3. 添加一個驅動
14.6.4. 去除一個驅動
14.7. 熱插拔


14.7.1. 動態設備
14.7.2. /sbin/hotplug 工具
14.7.3. 使用 /sbin/hotplug
14.8. 處理固件


14.8.1. 核心固件界面
14.8.2. 它如何工作
14.9. 快速參考


14.9.1. Kobjects架構
14.9.2. sysfs 操作
14.9.3. 匯流排, 設備, 和驅動
14.9.4. 類
14.9.5. 固件
15. 記憶體映射和 DMA


15.1. Linux 中的記憶體管理


15.1.1. 位址類型
15.1.2. 物理位址和頁
15.1.3. 高和低記憶體
15.1.4. 記憶體映射和 struct page
15.1.5. 頁表
15.1.6. 虛擬記憶體區
15.1.7. 進程記憶體映射
15.2. mmap 設備操作


15.2.1. 使用 remap_pfn_range
15.2.2. 一個簡單的實現
15.2.3. 添加 VMA 的操作
15.2.4. 使用 nopage 映射記憶體
15.2.5. 重新映射特定 I/O 區
15.2.6. 重新映射 RAM
15.2.7. 重映射核心虛擬位址
15.3. 進行直接 I/O


15.3.1. 異步 I/O

15.4. 直接記憶體存取


15.4.1. 一個 DMA 數據傳輸的概況
15.4.2. 分發 DMA 緩衝
15.4.3. 匯流排位址
15.4.4. 通用 DMA 層
15.4.5. ISA 設備的 DMA
15.5. 快速參考


15.5.1. 介紹性材料
15.5.2. 實現 mmap
15.5.3. 實現直接 I/O
15.5.4. 直接記憶體存取
16. 塊驅動


16.1. 註冊


16.1.1. 塊驅動註冊
16.1.2. 磁片註冊
16.1.3. 在 sbull 中的初始化
16.1.4. 注意扇區大小
16.2. 塊設備操作


16.2.1. open 和 release 方法
16.2.2. 支援可移出的介質
16.2.3. ioctl 方法
16.3. 請求處理


16.3.1. 對請求方法的介紹
16.3.2. 一個簡單的請求方法
16.3.3. 請求隊列
16.3.4. 請求的分析
16.3.5. 請求完成函數
16.4. 一些其他的細節


16.4.1. 命令預準備
16.4.2. 被標識的命令排隊
16.5. 快速參考

17. 網路驅動


17.1. snull 是如何設計的


17.1.1. 分發 IP 號
17.1.2. 報文的物理傳送
17.2. 連接到核心


17.2.1. 設備註冊
17.2.2. 初始化每一個設備
17.2.3. 模組卸載
17.3. net_device 架構的詳情


17.3.1. 全域訊息
17.3.2. 硬體訊息
17.3.3. 界面訊息
17.3.4. 設備方法
17.3.5. 公用成員
17.4. 打開與關閉
17.5. 報文傳送


17.5.1. 控制發送並發
17.5.2. 傳送超時
17.5.3. 發散/匯聚 I/O
17.6. 報文接收
17.7. 中斷處理
17.8. 接收中斷緩解
17.9. 連接狀態的改變
17.10. Socket 緩存


17.10.1. 重要成員變量
17.10.2. 作用於 socket 緩存的函數
17.11. MAC 位址解析


17.11.1. 以太網使用 ARP
17.11.2. 不考慮 ARP
17.11.3. 非以太網頭部
17.12. 定製 ioctl 命令
17.13. 統計訊息
17.14. 多播


17.14.1. 多播的核心支援
17.14.2. 典型實現
17.15. 幾個其他細節


17.15.1. 獨立於媒介的界面支援
17.15.2. ethtool 支援
17.15.3. netpoll
17.16. 快速參考
18. TTY 驅動


18.1. 一個小 TTY 驅動


18.1.1. 架構 struct termios

18.2. tty_driver 函數指標


18.2.1. open 和 close
18.2.2. 數據流
18.2.3. 其他緩衝函數
18.2.4. 無 read 函數?
18.3. TTY 線路設定


18.3.1. set_termios 函數
18.3.2. tiocmget 和 tiocmset
18.4. ioctls 函數
18.5. TTY 設備的 proc 和 sysfs 處理
18.6. tty_driver 架構的細節
18.7. tty_operaions 架構的細節
18.8. tty_struct 架構的細節
18.9. 快速參考
(繼續閱讀...)
文章標籤

立你斯 發表在 痞客邦 留言(0) 人氣(1,117)

  • 個人分類:driver 教學
▲top
  • 4月 26 週四 200700:33
  • LINUX-Writing the kernel console driver

LINUX-Writing the kernel console driver
  Writing the kernel console driver
1.寫一個核心控制台(console)驅動程式
  首先,核心需要一個非常簡單的序列驅動程式,它只允許輸出字元.為了盡可能的簡化它應該沒有中斷跟DMA.當核心使用printk()時他應該可以顯示任何訊息
  設一顆晶片叫做fic81xx建立 drivers/serial/fic81xx.c .在這個檔案需先引入下列檔案
  #include <linux/console.h>
  #include <linux/tty.h>
  #include <linux/tty_flip.h>
  #include <linux/serial.h>
  #include <linux/serial_core.h>
2.你必須寫兩個函式
  - static void foo_console_write(struct console *co, const char *s, unsigned count)
  可以寫入一些字串到序列埠,這裡建議使用輪詢代替中斷
  {
  1.除能中斷並儲存中斷設定值
  2.傳送字串(使用輪詢判斷是否字元已傳完並須判斷是否為行尾\n)
  3.等待傳完後回存中斷設定值
  }
- static __init int foo_console_setup(struct console *co, char *options),
  根據 options 給的設定來初始序列埠硬體.
3.現在寫一些console所需的結構
為了宣告新的console裝置 ,你的核心程式必須先引入<linux/console.h>.這裡定義了結構struct console 跟一些需要的旗標
struct console
  {
  char name[8]; //控制台裝置的名稱
  void (*write)(struct console *, const char *, unsigned); //列印核心訊息
  int (*read)(struct console *, const char *, unsigned); //
  kdev_t (*device)(struct console *);
  void (*unblank)(void); //the function, if defined, is used to unblank the screen
  int (*setup)(struct console *, char *); //
  short flags;
  short index; //the number of the device acting as a console in an array of devices
  int cflag;
  struct console *next;
  };
控制台(console)旗標
  The flags field is a bitmask, and linux-2.4 defines three flags:
  CON_ENABLED: the flag is used to tell whether or not this console device is enabled by default.
  As shown in listing 1, only enabled console devices receive kernel messages. The flag is set automatically by the system if one of the kernel command line options selects this console and setup and is successful. Moreover, the flag is set for the first console device that registers itself. That's why neither the serial nor the parallel consoles don't set the flag by default in struct console (see listing 2 and 2a): no serial or parallel port acts as a console by default unless the user asks for a serial or parallel console on the kernel command line or there exists no virtual-terminal device that can act as a default console.
  CON_PRINTBUFFER: the flags requests buffered messages to be dumped to this console device. The serial and parallel consoles, for example, display all kernel boot messages because of this flag: when a serial or parallel console is registered the flag is set, and the kernel immediately dumps all kernel messages that were printed earlier.
  CON_CONSDEV: the console asks to be the preferred console device. The preferred console device is placed first in the console list.
如下範例設定
static struct console sercons = {
  name: "ttyS",
  write: serial_console_write,
  device: serial_console_device,
  wait_key: serial_console_wait_key,
  setup: serial_console_setup,
  flags: CON_PRINTBUFFER,
  index: -1,
  };
ex;
  static struct console fic8120_console = {
  .name = "ttyS",
  .write = fic8120_console_write,
  // .read =
  .device = fic8120_console_device,
  // .unblank =
  .setup = fic8120_console_setup,
  .flags = CON_PRINTBUFFER,
  .index = -1,
  // .cflag =
  // .next =
  };

初始註冊一個console serial driver
  EX:
  void __init fic8120_console_init(void)
  {
  printk(KERN_INFO "FIC8120: serial console init\n");
  register_console(&fic8120_console);
  }

 
  參考文件
Serial">http://www.linux-mips.org/wiki/Serial_Driver_and_Console#Writing_the_kernel_console_driver">Serial Driver and Console
Serial">http://www.linux.it/%7Erubini/docs/sercons/sercons.html">Serial Consoles and Consoles in General
(繼續閱讀...)
文章標籤

立你斯 發表在 痞客邦 留言(0) 人氣(1,041)

  • 個人分類:driver 教學
▲top
  • 4月 26 週四 200700:32
  • LINUX-The Serial Driver Layer

LINUX-The Serial Driver Layer
The Serial Driver Layer
Registering a Serial Driver
--------------------------------
序列層要求你的驅動程式做兩件事情
1.註冊驅動程式它自己
2.註冊個人的序列埠 當它們被系統找到(經由PCI的列舉或其他裝置搜尋)
若要註冊自己的驅動程式請呼叫 uart_register_driver() 並傳入 struct uart_driver 的指標
這個函式取得 uart_driver 的資訊去初始狀態 並在uart core layer註冊一個驅動程式
註冊完後可在 /proc/tty/driver 出現相關資料
int uart_register_driver(struct uart_driver *drv)
下面是必須要提供的參數
struct module *owner;
const char *driver_name;
const char *dev_name;
int major;
int minor;
int nr;
struct console *cons;
下面是 uart_driver 結構內的參數/include/linux/serial_core.h
struct uart_driver {
struct module *owner;
int normal_major;
const char *normal_name;
struct tty_driver *normal_driver;
int callout_major;
const char *callout_name;
struct tty_driver *callout_driver;
struct tty_struct **table;
struct termios **termios;
struct termios **termios_locked;
int minor;
int nr;
struct console *cons;
/*
* these are private; the low level driver should not
* touch these; they should be initialised to NULL
*/
struct uart_state *state;
};
owner 是序列驅動程式的模組擁有者的指標,通常設定為一個巨集 THIS_MODULE 表示
driver_name 是指向這個驅動程式描述的指標通常與 dev_name 欄位相同. 然而當描述 dev_name 欄位時,若是 devfs 則必須加一個計數值, 如 ``%d'' 必須加在這個欄位最後一個字元. 這是因為 devfs 會建立裝置的 devfs節點.
如下例, 在 amba.c 驅動程式設定 driver_name 跟 dev_name 欄位:
.driver_name = "ttyAM",
#ifdef CONFIG_DEVFS_FS
.dev_name = "ttyAM%d",
#else
.dev_name = "ttyAM",
#endif
major 與 minor 欄位表示驅動程式的 major 號碼跟起始的minor號碼.
nr 表示這個驅動程式的序列埠支援的最大數目.
cons 是一個指向結構struct console的指標 ,若不支援serial console 則本欄位設為 NULL.
Registering a Serial Port
現在序列驅動程式已經完成serial driver layer的註冊
每一個序列埠需要呼叫uart_add_one_port()去個別的註冊
這個函式取得一個由uart_register_driver跟uart_port所傳來的 uart_driver指標
uart_port 結構定義如下/include/linux/serial_core.h
struct uart_port {
spinlock_t lock; /* port lock */
unsigned int iobase; /* in/out[bwl] */
char *membase; /* read/write[bwl] */
unsigned int irq; /* irq number */
unsigned int uartclk; /* base uart clock */
unsigned char fifosize; /* tx fifo size */
unsigned char x_char; /* xon/xoff char */
unsigned char regshift; /* reg offset shift */
unsigned char iotype; /* io access style */
unsigned int read_status_mask; /* driver specific */
unsigned int ignore_status_mask; /* driver specific */
struct uart_info *info; /* pointer to parent info */
struct uart_icount icount; /* statistics */
struct console *cons; /* struct console, if any */
#ifdef CONFIG_SERIAL_CORE_CONSOLE
unsigned long sysrq; /* sysrq timeout */
#endif
unsigned int flags;
unsigned int mctrl; /* current modem ctrl settings */
unsigned int timeout; /* character-based timeout */
unsigned int type; /* port type */
struct uart_ops *ops;
unsigned int line; /* port index */
unsigned long mapbase; /* for ioremap */
unsigned char hub6; /* this should be in the 8250 driver */
unsigned char unused[3];
};
低階序列硬體驅動程式
--------------------------------
低階序列硬體驅動程式是由所支援的埠資料(uart_port)跟一個控制方法(uart_ops)給core serial driver
它也可由埠支援中斷操作跟console
console支援
---------------
serial_core提供相對應的函式包括可認到正確的埠架構(uart_get_console)跟命令列解碼(uart_parse_options)
Locking
-------
一般而言,除了中斷功能外,全部的鎖都由核心驅動.這表示低階的硬體驅動程式必須去操作鎖(使用info->lock)
若操作在中斷期間則只需使用 spin_lock() 跟 spin_unlock()
uart_ops
--------
uart_ops結構是介於serial_core與硬體特定驅動程式主要的介面.它包含全部的硬體的控制方法
ops欄位 是結構 struct uart_ops
定義如下
struct uart_ops {
unsigned int (*tx_empty)(struct uart_port *);
void (*set_mctrl)(struct uart_port *,unsigned int mctrl);
unsigned int (*get_mctrl)(struct uart_port *);
void (*stop_tx)(struct uart_port *, unsigned int tty_stop);
void (*start_tx)(struct uart_port *, unsigned int tty_start);
void (*send_xchar)(struct uart_port *, char ch);
void (*stop_rx)(struct uart_port *);
void (*enable_ms)(struct uart_port *);
void (*break_ctl)(struct uart_port *, int ctl);
int (*startup)(struct uart_port *);
void (*shutdown)(struct uart_port *);
void (*change_speed)(struct uart_port *, unsigned int cflag,unsigned int iflag, unsigned int quot);
void (*pm)(struct uart_port *, unsigned int state,unsigned int oldstate);
int (*set_wake)(struct uart_port *, unsigned int state);
/*
* Return a string describing the port type
*/
const char *(*type)(struct uart_port *);
/*
* Release IO and memory resources used by
* the port. This includes iounmap if necessary.
*/
void (*release_port)(struct uart_port *);
/*
* Request IO and memory resources used by the
* port. This includes iomapping the port if
* necessary.
*/
int (*request_port)(struct uart_port *);
void (*config_port)(struct uart_port *, int);
int (*verify_port)(struct uart_port *,struct serial_struct *);
int (*ioctl)(struct uart_port *, unsigned int,unsigned long);
};
tx_empty(port)
若是空的,它將返回 TIOCSER_TEMT ,其他情形則返回0
若埠不支援這個功能則應返回TIOCSER_TEMT
set_mctrl(port, mctrl)
適當的mctrl 控制BIT為
- TIOCM_RTS RTS 信號.
- TIOCM_DTR DTR 信號.
- TIOCM_OUT1 OUT1 信號.
- TIOCM_OUT2 OUT2 信號.
若相關的BIT被設定則信號將被驅動,若相關的BIT被清除則信號也相被除能
get_mctrl(port)
返回 mctrl 現在的狀況
- TIOCM_DCD DCD 狀態
- TIOCM_CTS CTS 狀態
- TIOCM_DSR DSR 狀態
- TIOCM_RI RI 狀態
若port沒有支援 CTS, DCD or DSR, 則驅動程式應該指示這些信號永遠是動作的.
stop_tx(port,from_tty)
停止傳送字元
這表示CTS變的不活動或tty layer指示我們要去停止傳送
start_tx(port,nonempty,from_tty)
開始傳送字元
stop_rx(port)
停止接收字元
enable_ms(port)
致能modem狀態中斷
break_ctl(port,ctl)
傳送一個break 信號.
若 ctl 不為零, 則 break 信號應該被傳送.
當 ctl 為零時break 信號就應該被停止傳送
startup(port,info)
抓取任何中斷資源跟初始低階驅動程式狀態並致能port
shutdown(port,info)
與startup函式功能相反,關閉port及任何有影響的break條件,而所有startup函式所配置的資源全部釋放
change_speed(port,cflag,iflag,quot)
改變這個埠的參數,包括字元的長度,同位元,停止位元.
更新 read_status_mask 跟 ignore_status_mas
相關的 cflag 控制模式旗標為
CSIZE - word size
CSTOPB - 2 個停止位元
PARENB - 致能同位元
PARODD - 奇同位 (when PARENB is in force)
CREAD - 致能接收字元 (若沒設定 仍然可以接收字元但會丟棄)
CRTSCTS - 致能 CTS 狀態改變報告
CLOCAL - 若沒設定 致能modem 狀態改變報告.
相關的 iflag 輸入模式旗標為:
INPCK - 致能框架與同位元錯誤事件給 TTY layer.
BRKINT
PARMRK - 這兩個都是致能 brea 事件給 TTY layer.
IGNPAR - 忽視同位元跟框架錯誤
IGNBRK - 忽視break錯誤 若 IGNPAR 也被設定, 則忽視溢位錯誤 (overrun errors).
在 iflag 輸入模式旗標 設定與同位元錯誤有不同的影響:
Parity error INPCK IGNPAR
None n/a n/a 接收字元
Yes n/a 0 丟棄字元
Yes 0 1 接收字元, 註記 TTY_NORMAL
Yes 1 1 接收字元, 註記 TTY_PARITY
pm(port,state,oldstate)
set_wake(port,state)
若你的硬體平台有支援電源管理 使用這些函式去掌控硬體電源管理
'state' 定義如 ACPI D0-D3
'oldstate' 指示之前的狀態
基本上 D0表示全開 D3表示全關
下面這些函式被使用來抓取任何有關資源
type(port)
返回序列埠的描述 被使用在 /proc/tty/driver/ 跟 boot 起來時發現到這個埠所出現的訊息
release_port(port)
釋放這個port有關的記憶體與IO區域資源
request_port(port)
要求這個port有關的記憶體與IO區域資源
若要求失敗則應該沒有任何資料有被配置並返回 -EBUSY
config_port(port,type)
'type'種類
UART_CONFIG_TYPE 表示不要求偵測跟辨別.當 型態有被找出則 port->type 應被設定 若沒被找出則設為 PORT_UNKNOWN
UART_CONFIG_IRQ 表示在中斷信號下自動安裝,應該被探測在標準的核心自動探測技術,(這不是必須的)
verify_port(port,serinfo)
用來確認序列埠設定是否合法 跟 當使用者產生 ioctl 的 TIOCSSERIAL 時
Verify the new serial port information contained within serinfo is
suitable for this port type.
ioctl(port,cmd,arg)
執行任何 port 特定的 IOCTLs.
IOCTL 必須只能使用在 <asm/ioctl.h> 的定義
Other notes
-----------
為了將來的擴充性
可以建立自己個人的uart_port
struct my_port {
struct uart_port port;
int my_stuff;
};
Where Is the Data?
--------------------------------
你可能注意到這裡沒有函式是去做傳跟收資料
使用者傳資料時藉由serial driver layer,經由tty layer 呼叫 write() 去配置環狀緩衝區
然後由UART driver取得這些資料並從這個埠送出
通常每次UART中斷發生 若有資料要去傳送則驅動程式去確認環狀緩衝區
TX範例如下
static void tiny_tx_chars(struct uart_port *port)
{
struct circ_buf *xmit = &port->info->xmit;
int count;
if (port->x_char) {
/* send port->x_char out the port here */
UART_SEND_DATA(port->x_char);
port->icount.tx++;
port->x_char = 0;
return;
}
if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
tiny_stop_tx(port, 0);
return;
}
count = port->fifosize >> 1;
do {
/* send xmit->buf[xmit->tail] out the port here */
UART_SEND_DATA(xmit->buf[xmit->tail]);
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
port->icount.tx++;
if (uart_circ_empty(xmit))
break;
} while (--count > 0);
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_event(port, EVT_WRITE_WAKEUP);
if (uart_circ_empty(xmit))
tiny_stop_tx(port, 0);
}
函式一開始由x_char來指示是否有現在資料要傳。
如果有資料,開始傳送且累計計數值後返回。
如果沒有,查看環狀緩衝區是否還有資料和埠現在是否已經停止。
若成立,我們開始從環狀緩衝區中取出字元並且把它們送到UART。
在這個例子裡e,我們最多只送出FIFO大小的一半,這是為了可以平均的送出字元。
送完字元後,判斷環狀緩衝區是否可接受更多字元。
若可以呼叫uart_event()傳入EVT_WRITE_WAKEUP 喚醒參數,通知序列核心去告知用戶端,我們能接受更多的數據。
這些收傳動作都是在中斷內發生。
UART中斷範例
/*
* This is the serial driver's interrupt routine.
*/
static void fic8120_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
struct fic8120_port *up = (struct fic8120_port *) dev_id;
unsigned char lsr;
DBG("%s(): ", __FUNCTION__);
spin_lock(&up->port.lock);
lsr = serial_in(up, FIC8120_LSR);
if (lsr & FIC8120_LSR_DR)
fic8120_rx_chars(up, &lsr, regs);
fic8120_check_mstatus(up);
if (lsr & FIC8120_LSR_THRE)
fic8120_tx_chars(up);
spin_unlock(&up->port.lock);
}
(繼續閱讀...)
文章標籤

立你斯 發表在 痞客邦 留言(0) 人氣(6,227)

  • 個人分類:driver 教學
▲top
  • 4月 26 週四 200700:31
  • LINUX-Linker scripts



LINUX-Linker scripts
Linker command scripts

下面範例將討論每個章節的細節
概括的說它定義了四個記憶體區塊( vect, rom, ram and cache)跟五個區段(vect, text, bss, init, and stack)
在採用段式記憶體管理的架構中,BSS段(bss segment)通常是指用來存放程序中未初始化的全局變數的一塊記憶體區域。
BSS是英文Block Started by Symbol的簡稱。BSS段屬於靜態記憶體分配。
在採用段式記憶體管理的架構中,數據段(data segment)通常是指用來存放程序中已初始化的全局變數的一塊記憶體區域。
數據段屬於靜態記憶體分配。
範例
/* a list of files to link (others may be supplied on the command line) */
INPUT(libc.a libg.a libgcc.a libc.a libgcc.a)

/* output format (can be overridden on command line) */
OUTPUT_formAT("coff-sh")
/* output filename (can be overridden on command line) */
OUTPUT_FILENAME("main.out")
/* our program’s entry point; not useful for much except to make sure the S7 record
is proper, because the reset vector actually defines the "entrypoint" in most embedded systems */

ENTRY(_start)
/* list of our memory sections */
MEMORY
{
vect : o = 0, l = 1k
rom : o = 0x400, l = 127k
ram : o = 0x400000, l = 128k
cache : o = 0xfffff000, l = 4k
}
/* how we’re organizing memory sections defined in each module */
SECTIONS
{
/* the interrupt vector table */
.vect :
{
__vect_start = .;
*(.vect);
__vect_end = .;
} > vect
/* code and constants */
.text :
{
__text_start = .;
*(.text)
*(.strings)
__text_end = .;
} > rom
/* uninitialized data */
.bss :
{
__bss_start = . ;
*(.bss)
*(COMMON)
__bss_end = . ;
} > ram
/* initialized data */
.init : AT (__text_end)
{
__data_start = .;
*(.data)
__data_end = .;
} > ram
/* application stack */
.stack :
{
__stack_start = .;
*(.stack)
__stack_end = .;
} > ram
}
注意!
ld將使用預設的命令檔,除非你告訴它使用其他方法
去指示ld去使用你的命令檔則給gcc -Wl,T OUTPUT_formAT命令
支援多種格式的輸出檔,包括S-records (srec), binary (binary), Intel Hex (ihex), 跟數個 debug-aware formats
像是COFF (coff-sh for SH-2 targets, coff-m68k for CPU32, 等等.)
使用objdump工具去找到你的linker版本有支援的格式
MEMORY命令
MEMORY命令描述目標系統的記憶體映射
典型簡單的語法如下
MEMORY {
name : o = origin, l = length
name : o = origin, l = length
...
}
SECTIONS命令
在SECTIONS命令的述語(Statements)是描述每一個輸出區段的配置而且詳細述語輸入區段
你可以只允許一個SECTIONS述語(Statements)在每個命令檔
但如果必要的話也可以有很多述語(Statements)在裡面
在這個例子,述語(statement)如下
/* code and constants */
.text :
/*一開始定義一個區段叫'.text'然後將述語(Statements)包含在{}裡*/
{
__text_start = .;
/*建立一個符號 叫__text_start 而且配置區段起始點*/
*(.strings)
*(.text)
/*合併全部輸入檔的.text 和 .strings 到這各個區段*/
__text_end = .;
/*建立一個符號 叫__text_end 而且配置區段結束點*/
/*最後結束述語*/
} > rom
/*告訴連結器(linker)定這個記憶體區段叫'rom' 根據MEMORY命令知道起始位址為0X400*/
輸入區段的列表也可以被歸成特定的檔案.如你增加一個像 foo.o (.specialsection)
到.text區段定義,然而連結器也將檔案foo.o的.specialsection區段合併到.text
bss/ data / code 相關概念 如下圖所示



AT指令
AT指令去告訴連結器(linker)去載入區段的資料到何處,
最好的了解AT指令的方法就是用例子解釋
所以考慮一個應用在只有一個初始全域變數
int a_global = 102;
在編譯的時候,gcc將宣告一個整數物件 a_global 跟 值=102 在模組的.data區段
但在連結.data區段時藉由一個AT指令,我們告訴連結器去分配a_global在一個位置(如RAM)的位址.但配置初始值到其他的地方(如 __text_end , 通常是 ROM)
跟隨著code初始a_global(跟其他初始的全域資料)
這個code使用符號_text_end, _data_start , 跟 _data_end 去找到初始值,決定它的大小跟配置它到RAM適當的位置
extern const char _text_start,
_text_end;
extern char _data_start,
_data_end;
memcpy( &_data_start, &_text_end,
&_data_end - &_data_start );
現在把它全部放在一起,跟隨命令列告訴gcc去編譯一個檔案 main.c 而且連結它使用 連結命令檔案 main.cmd gcc -g -Wl,-Tmain.cmd main.c

//-----------------------------------------------------------------------------------------
範例 u-boot lds
    下面,結合u-boot.lds看看一個正式的連接腳本檔案。這個檔案的基本功能還能看明白,雖然上面分析了好多,但其中那些GNU風格的符號還是著實讓我感到迷惑,好菜啊,怪不得連被3家公司鄙視,自己鄙視自己。。。
OUTPUT_FORMAT("elf32­littlearm", "elf32­littlearm", "elf32­littlearm")
  ;指定輸出可執行檔案是elf格式,32位ARM指令,小端
OUTPUT_ARCH(arm)
  ;指定輸出可執行檔案的平台為ARM
ENTRY(_start)
  ;指定輸出可執行檔案的起始代碼段為_start.
SECTIONS
{
        . = 0x00000000 ; 從0x0位置開始
        . = ALIGN(4) ; 代碼以4位元組對齊
        .text : ;指定代碼段
        {
          cpu/arm920t/start.o (.text) ; 代碼的第一個代碼部分
          *(.text) ;其它代碼部分
        }
        . = ALIGN(4)
        .rodata : { *(.rodata) } ;指定只讀數據段
        . = ALIGN(4);
        .data : { *(.data) } ;指定讀/寫數據段
        . = ALIGN(4);
        .got : { *(.got) } ;指定got段, got段式是uboot自定義的一個段, 非標準段
        __u_boot_cmd_start = . ;把__u_boot_cmd_start賦值為當前位置, 即起始位置
        .u_boot_cmd : { *(.u_boot_cmd) } ;指定u_boot_cmd段, uboot把所有的uboot命令放在該段.
        __u_boot_cmd_end = .;把__u_boot_cmd_end賦值為當前位置,即結束位置
        . = ALIGN(4);
        __bss_start = .; 把__bss_start賦值為當前位置,即bss段的開始位置
        .bss : { *(.bss) }; 指定bss段
        _end = .; 把_end賦值為當前位置,即bss段的結束位置
}
 
 
相關連結
http://www.delorie.com/gnu/docs/binutils/ld.html#SEC_Top
 
 
对多个输入文件进行链接得到一个输出文件
节:节名称,大小,节数据
输入节:输入文件中的节
输出节:输出文件中的节
加载节:节内数据,在运行时,被加载到内存
重加载节:节内无数据,在内存中要预留一个空间
调试节:含调试信息的节
符号名:带双引号, 不带双引号(不能同已有的关键字冲突)
在输入节中,未处理的孤儿节,被链接器放置在具有相同属性节的后面,若放不下,则放在文件尾部
ALIGN(align)  按指定数据对齐
ALIGN(exp,align)  按指定数据对齐 等同于ALIGN(.,align)
ORIGIN(ram) 计算内存区域的起址地址
LENGTH(ram) 计算内存区域的长度
. 表示定位计数器
VMA(virtual memory address):运行时的地址
LMA(load memory address):存储地址
输出节
SECTION [ADDRESS] [(TYPE)] : [AT(LMA)]
      {
        OUTPUT-SECTION-COMMAND
        OUTPUT-SECTION-COMMAND
        ...
      } [>REGION] [AT>LMA_REGION] [:PHDR :PHDR ...] [=FILLEXP]
SECTION输出节名
ADDRESS:运行的地址,若无,则用REGION设置它,若也无REGION,则用当前定位计数器
TYPE:默认即可, 也可用NOLOAD表示,这个节,运行时不加载
>REGION 将这个输入节放到哪个内存中
LMA_REGION
=FILLEXP 填充空白的数据
 
自定义一个内存区域
MEMORY
  {
    name [(attr)] : ORIGIN = origin, LENGTH = len
    …
  }
name 内存区名称
attr 属性  R W X A(Allocatable section) I(Initialized section) L(Same as 'I') !(插入以前的属性)
ORIGIN  开始地址
 LENGTH 区域长度
程序头
PHDRS
{
  name type [ FILEHDR ] [ PHDRS ] [ AT ( address ) ]
        [ FLAGS ( flags ) ] ;
}
(繼續閱讀...)
文章標籤

立你斯 發表在 痞客邦 留言(1) 人氣(6,349)

  • 個人分類:編譯相關
▲top
  • 4月 26 週四 200700:29
  • LINUX-Fedora Core 6 安裝

LINUX-Fedora Core 6 安裝方法

Fedora Core 6 安裝方法


1.要用圖形介面請按【enter】→ 請選它
2.要用文字介面,輸入:linux text
3.使用功能鍵列出以下資訊

◆是否要測試CD-ROM,選【skip】
◆按【下一步】
◆選【繁體中文】,按【下一步】
◆選預設【美式英文】,按【下一步】
◆按【是】
◆選【建立自訂的分割模式】,按【下一步】
◆假設硬碟分割大小13G,按【新增】
◆檔案系統掛載點選【/】,檔案系統類型預設【ext3】,輸入大小【12800】MB,完成之後按【確定】

◆選未分割區,按【編輯】

◆檔案系統類型選【swap】,按【確定】;swap是虛擬記憶體,設定大小以實體記憶體為主

◆分割完成,按【下一步】
◆如果其他分割區有裝作業系統(如:Windows XP),就按【新增】;如沒有,按【下一步】
◆設定網路裝置IP位址
◆輸入【IP】和【Netmask】,按【確定】
◆輸入【主機名稱】、【閘道器之IP】和【主DNS之IP】,按【下一步】
◆用預設值,按【下一步】
◆輸入root【密碼】,按【下一步】
◆選擇要安裝的軟體,選【立即自訂】,按【下一步】
◆選擇您所需要安裝的軟體,按【下一步】
◆正在檢查安裝套件的相依性 . . . . . . . .
◆按【下一步】
◆正在安裝套件 . . . . . . . . .
◆安裝完成,按【重新開機】
◆在進入 Fedora Core Linux 6 之前,顯示歡迎畫面設定,按【下一頁】
◆選【是的】,按【下一頁】
◆防火牆設定,按【下一頁】

◆SELinux 設定,按【下一頁】

◆日期與時間的設定,按【下一頁】


◆是否建立使用者,按【下一頁】



◆音效卡設定,按【完成】

◆進入 Fedora Core Linux 6 登入畫面

◆進入 Fedora Core Linux 6 桌面環境


(繼續閱讀...)
文章標籤

立你斯 發表在 痞客邦 留言(0) 人氣(403)

  • 個人分類:系統相關
▲top
  • 4月 26 週四 200700:27
  • USB On-The-Go 技術概述


USB On-The-Go 技術概述
USB On-The-Go 技術概述
0 什麼是USB On-The-Go
我們先來回顧一下通用串列匯流排(Universal Serial Bus,簡稱為USB)發展的歷史:

1994 年11 月
,以Intel 為首的7 家公司(Intel、Compaq、Microsoft、IBM、DEC、Northern Telecom 和NEC)推出了USB 協議的第一個草案,USB 作為一種新型的串列匯流排,揭開了新一輪的USB 匯流排的革命,但這時,USB 並不為電腦技術人員所熟知;

1996 年2 月
,USB 協定規範1.0 版本發佈,版權屬於Compaq、Intel、Microsoft和NEC 等4 家公司,並同意任何人可免費使用。自此,USB 開始逐漸被廣大技術人員和用戶所認可,並逐漸開始成為PC 主板上的標準介面;
1998 年10 月,USB 1.1 版本發佈,集中修訂了USB 1.0 中的問題,並進一步突出了USB 的優勢。到目前,USB 1.1 仍是開發USB 低速(1.5Mbps,Low-Speed)和全速(12Mbps,Full-Speed)設備的標準版本。USB 的低功耗、速度高、成本低、支持即插即用和維護方便等優勢更加穩定,USB 開始成為滑鼠、鍵盤、遊戲杆、印表機、光碟機、硬碟、顯示器和數碼相機等幾乎各種PC 外接設備與PC 連接的標準協議之一。各種USB 的外接設備產品如雨後春筍般出現,如USB Flash 讀卡器、USB 移動硬碟、USB 數碼相機、USB 鍵盤等,幾乎所有的PC 外接設備都有相應的USB 介面的產品。一時間,USB 成為了最為流行的PC 介面標準,嵌入式軟硬體工程師也將USB 應用到自己的設計之中;
2000 年4 月,Compaq、HP、Intel、Lucent、Microsoft、NEC 和Philips 等7 家公司聯合發佈USB 2.0 協定規範版本。新版本最大的變化就是將USB 的總線速度一下子提高到了480Mbps,即開始支援高速設備(High-Speed)。由此,USB 翻開了新的一頁,徹底打破了USB 應用在視頻等高速傳輸領域中的速度瓶頸,大大擴展了USB 應用領域。從低速的滑鼠、鍵盤,到全速的硬碟,再到高速的視頻傳輸,USB 幾乎無所不能,可以應用到任何一種PC 外接設備中。USB 取代串口、並口等傳統PC 介面只是個時間問題了。
從問世,到協定規範2.0 版本,USB 不斷在自我完善,走向成熟。從普通電腦用戶,電腦工程師,到硬體晶片生產廠商,都已經完全認可了USB。廠商對於USB 的硬體和軟件支援的也越來越完備,現在開發一個USB 外接設備產品,所需要投入的成本和時間大大降低了,幾年前是沒有辦法做到這一點的。但是,隨著USB 應用領域的逐漸擴大,人們對於USB的期望也越來越高,希望USB 能應用在各種電腦領域中,尤其是在移動通訊領域中,希望能通過PDA 等移動設備來直接和USB 外接設備通信,使得USB 能應用在沒有PC 的領域中。
非PC 應用領域?
這正是USB 一個致命的弱點。USB 的拓撲結構中居於核心地位的是Host,任何一次USB 的資料傳輸都必須由Host 來發起和控制,所有的USB 外接設備都只能和Host 建立連接,任何兩個外接設備之間或是兩個Host 之間無法直接通信。而目前,大量的扮演Host 角色的是個人電腦PC。因此,“如何將USB 應用到嵌入式領域?如何實現USB 點對點的通訊?”等問題,開始進入了USB 開發者的討論議程。正是在這種新的需求之下,USB On-The-Go 應運而生。
2001 年12 月,USB On-The-Go 版本協議1.0 正式發佈(簡寫為OTG 1.0)。
USB On-The-Go,顧名思義,是USB 應用在攜帶型移動設備領域中,因此,我們姑且將其翻譯為“攜帶型USB”(或者“移動USB”),簡記成USB OTG。OTG 1.0 作為USB 2.0的補充協定,基本上符合USB 2.0 規範。但是,有所不同的是符合USB OTG 的設備完全拋開了PC,既可以作為Host,也可以作為外接設備,而與另一個OTG 設備直接實現點對點(Pearto Pear)通訊。因此,這類OTG 設備也被成為是雙角色設備(Dual-Role Device,簡稱為DRD),並能夠根據接入設備的特性和資料傳輸過程中的情況,自動切換為Host 或是外接設備。
例如,一個OTG 數碼相機可以直接與OTG 印表機相連,列印圖片;兩個OTG MP3 播放器可以之間連在一起,實現音樂檔的共用..需要注意的是,USB OTG 設備保留了作為普通USB 2.0 外接設備的功能,可以作為外接設備直接連接到PC Host 上。
USB的廣泛應用使其正在成為外接設備與PC機及膝上型電腦連接的工業標準。USB外接設備主要是便攜式設備,隨著其數量的不斷增多,設備之間無主機參與的直接通信成為亟待解決的問題。我們開發了基於USB匯流排(界面晶片為Philips公司的PDIUSBD12)的數據采集系統,取得了滿意的效果。但在開發USB1。1設備時遇到的設備互連直接通信的要求,一直由於USB主機/設備架構的制約沒有理想的解決方案。USB2。0雖然在速度等方面有很大的改進,但同樣要倚賴計算機主機進行通信。  2001年底,USB開發者論壇(USBImplementersForum,USBIF)發布了專門用於USB外接設備間"可移動互連"的USB2。0補充規範USBOn-The-Go,其目標是使外接設備以主機的身分和另外特定的一組外接設備直接通信。本文中歸納USB2。0補充規範OTG的相關技術,並主要討論其新增特性。
1新的協議
OTG補充規範對USB2。0的最重要的擴展是其更具節能性的電源管理和允許設備以主機和外接設備兩種形式工作。OTG有兩種設備類型︰兩用OTG設備(Dual-roledevice)和外接設備式OTG設備(Perip-heral-onlyOTGdevice)。兩用OTG設備完全符合USB2。0規範,同時它還要提供有限的主機能力和一個MiniAB插座、支援主機流通協議(HostNegotiationProtocol,HNP),並和外接設備式OTG設備一樣支援事務請求協議(SessionRequestProtocolSRP)。當作為主機工作時,兩用OTG設備可在匯流排上提供8mA的電流,而以往標準主機則需要提供100~500mA的電流。
兩個兩用OTG設備連接在一起時可交替以主機和從機的模式工作,這個特點兼容了現有USB規範主機/外接設備的架構模型。OTG主機同樣負責初始化數據通信的任務,比如︰匯流排複位、獲取USB各種描述符和配置設備。這些配置完成後,兩個OTG設備便可以分別以主機和從機模式傳輸訊息,兩個設備主從角色交換的過程由主機傳輸協議(HNP)定義。以下以兩用OTG設備為例討論SRP和HNP。
1。1事務請求協議SRP
在以往的USB系統營運過程中,主機提供5V的電源和不低於100mA的匯流排電流。當OTG主機(指以主機模式工作的兩用OTG設備,又稱A-device)連接到有線電源時這種方法是適用的,但像手機這樣的自供電移動設備則不能承受如此大的電能浪費。為了節約電源延長電池的使用壽命,當匯流排上沒有活動時,OTG主機將掛起匯流排電源VBUS。SRP協議可使OTG從機(指外接設備式設備或者以外接設備模式工作的兩用OTG設備,又稱B-device,此處指後者)請求A-device重新使能VBUS,而後A-device使用HNP協議交換兩個設備的工作模式,這兩步完成後由新的OTG主機開始事務傳輸。B-device可在前一事務結束2ms後的任意時間開始SRP。
B-device將先後執行數據線脈波調製(data-linepul-sing)和VBUS脈波調製(VBUSpulsing)。它透過使能數據線上拉電阻(全速和高速設備為D+,低速設備為D-)5~10ms實現前者,後者透過驅動VBUS實現。VBUS必須要有足夠長的時間對其電容充電,這個時間應能保證不大於13μF的電容充電至2。1V(OTG設備的電容是6。5μF或更小),從而不會對標準主機的96μF或更高的電容充電至2。0V。該限制保證了從B-device引來的VBUS電流不會破壞標準主機的端口。
A-device檢測到數據線脈波調製或者VBUS脈波調製後,首先複位匯流排,然後發送Set_feature命令而先不進行設備的枚舉,此時B-device尚處在預設的從機狀態。如果Set_feature命令成功執行,說明B-device為兩用OTG設備,A-device(使用HNP協議)掛起VBUS準備讓B-device交換為主機模式接管匯流排。如果Set_feature命令執行失敗,說明B-device為外接設備式OTG設備,於是A-device使能VBUS準備開始一個傳輸事務。此時,A-device只是被喚醒,並未改變工作模式。當A-device認為匯流排上沒有傳輸需要時,掛起VBUS以結束該事務。這種A-device自動檢測B-device是否支援HNP協議的特徵稱為“NoSilentFailure”。
1。2主機流通協議HNP
當兩用設備連接了一個Mini-A插頭或者Mini-B插頭時,它相應的便以OTG主機或者OTG外接設備的預設模式工作。A-device為預設主機,所以由它提供VBUS電源,且在檢測到有設備接入時複位匯流排、枚舉並配置B-device。
A-device在完成對B-device的使用後,可以透過查詢B-device的OTG性能描述符來判斷它是否支援HNP協議(即是否為兩用OTG設備)。如支援HNP,B-device將返回有效的OTG性能描述符,A-device則產生一個Set_feature命令(即HNP_Enable)來通知B-device可以在匯流排掛起的時候以主機模式工作,隨後A-device掛起匯流排。
B-device透過上拉電阻(全速時)或者下拉電阻(高速時)拉低D+以示連接斷開。隨後,作為對B-device斷開的附應,A-device使能它的數據線並開始以從機模式工作。完成這些轉換後,B-device和A-device便各自以主機角色和外接設備角色使用匯流排。如果該B-device屬於兩用OTG設備且A-device不再使用它了,A-device便重發Set_feature命令並掛起匯流排。若B-device申請角色轉換時出錯,A-device則拉低VBUS以結束該事務。當B-device正常結束傳輸事務時便掛起VBUS使能其上拉電阻,重新以從機模式營運。A-device檢測到匯流排掛起後,發出一個連接斷開信號並重新以主機模式工作。
2.USB OTG 的機械層和電氣層協議
2。1連接器
USBIF在OTG中定義了更小的連接器,可以同時用於主機式和外接設備式的設備、具有更低的電源需求、擴展的電源保護模式和利於上層軟體開發的簡潔設計。
OTG和現有的USB2。0規範完全兼容,一個主要的機械上的改進是它的新式連接器。USB2。0定義了三種連接器對(插頭和插座)︰Standard-A、Standard-B和Mini-B。Mini-B連接器是專為較小的外接設備(如移動電話等)開發的。OTG規範增加了第四種插頭?Mini-A,兩種插座︰Mini-A和Mini-AB。這些連接器比最初的USB連接器要小許多(如︰Mini-A插頭截面積只有Standard-A插頭的38%),更適合於便攜式設備。
Mini-AB插座用於兩用設備。Mini-A新增的ID腳(以前的USB插頭不含此腳)在連接Mini-AB時接地短路,而Mini-B則使該腳斷開,這樣兩用設備便可識別連接設備的類型以決定設備的預設角色。
Mini-A和Mini-B插頭是嚴格配對適用的,如︰不能將Mini-A插頭和Mini-B插座配合使用。但是,Mini-AB插座適合於以上兩種插頭。在外形上,Mini-A更接近於橢圓形,而Mini-B更接近於正方形。另外,他們的插頭和插座內部的塑膠都有顏色︰Mini-A為白色,Mini-B為黑色,Mini-AB為灰色。
2。2電纜
USB2。0規範定義了兩種電纜︰Standard-A至Standard-B和Standard-A至Mini-B。OTG新增了兩種電纜︰Mini-A至Standard-B和Mini-A至Mini-B。Mini-A-to-Mini-B電纜的延遲被減少到可以在"A端〃使用適配器,如︰用Standard-A插頭連接OTG兩用設備需要一個Standard-A插座至Mini-A插頭的適配器,而用Mini-A插頭連接Standard-A插座時需要一個Mini-A插座至Standard-A插頭的適配器。
2.3 USB OTG 匯流排的電流要求

在USB OTG 系統中,A 設備(指處於Host 地位的設備)必須至少為匯流排提供8mA 的電流,電壓為4.4~5.25V。如果A 設備能提供100mA 以上的電流,那麼,電壓範圍為4.75~5.25V。在未被配置的情況下,OTG DRD 所提取的電流不得超過150uA,而POD 提取的電流不得超過8mA。
 
3USBOn-The-Go設備類型
OTG有兩種設備︰兩用OTG設備和外接設備式OTG設備。兩用OTG設備可以作為USB外接設備或者USBOTG主機,並且可為匯流排提供8mA電流。而外接設備式OTG設備不具備主機性能,它必須在向兩用設備(主機)的請求獲準後才能通信。兩用OTG設備必須能以全速模式營運,而高速營運的模式是可選的。外接設備型OTG設備可以設計在高速、全速和低速中的任意一種模式下工作。
3。1兩用OTG設備
兩用OTG設備都有一個Mini-AB插槽,所以一個Mini-A至Mini-B電纜可以直接將兩個兩用OTG設備連接在一起,而此時用戶不會覺察到兩個設備的不同,也不知道它們的預設主從配置。
A-device主機必須在事務傳輸過程中提供匯流排電源,這是A-device和B-device的主要不同,同時也說明了兩個設備的連接的非對等關係。A-device負責為匯流排供電因此它控制通信發生的時機,B-device只有透過SRP協議向"主機"請求傳輸。
設計一個兩用設備是比較困難的,因為它要具備︰有限的主機能力、可作為一個全速的外接設備(可選的高速模式)、OTG目標設備的清單、目標設備的驅動程式、支援SRP、支援HNP、一個Mini-AB插座、VBUS上不小於8mA的電流輸出、與用戶通信的模式。
3。2外接設備式OTG設備(Peripheral-onlyOTGdevice)
外接設備式OTG設備是普通的USB外接設備。它有一個OTG功能描述符說明其支援事務請求協議SRP而且它不是兩用OTG設備。此外,外接設備式OTG設備只能配置Mini-B型插座或者必須有一個帶Mini-A插頭的附屬電纜,而不能使用Mini-AB型插座。
SRP是B-device(此處指外接設備式設備)向A-device請求傳輸事務時必須使用的協議。它由前面提到的數據線脈波調製和VBUS脈波調製(B-device產生)兩種方法構成。A-device必須能檢測這兩種方法之一的信號,並開始一個相應的傳輸事務。除了固件(firmware)略有增加外,B-device同時可產生兩種信號的成本並沒有增加成本,而且還使實現A-device更加簡單(只需根據實際情況提供其中一種模式的檢測)。
一個OTG設備不必實現OTG的所有性能。例如,一個外接設備式OTG設備可能只需支援SRP和一個小於等於8mA的預設電流消耗配置。其實,添加對SRP支援也較簡單︰在VBUS上接一個驅動電阻並增加一些簡單的邏輯,從而產生VBUS脈波調製信號。
另外,無論是兩用OTG設備還是外接設備式OTG設備,都可以和通用的計算機相連,只不過兩用OTG設備具有一定的主機能力(可以驅動特定的一組OTG設備工作)。
4驅動程式
與PC主機不同,便攜式設備沒有便捷的模式和足夠的空間裝載新的驅動程式。因此,OTG規範要求每個兩用OTG設備有一個支援的外接設備式OTG目標設備的清單,清單中包括設備的類型和製造商等訊息。USBIF正計畫定義"OTGType"規範。對於符合此規範的設備,OTG主機只需提供一個驅動程式即可,這將使OTG主機無需為每個設備提供單獨的驅動程式,從而支援盡量多的OTG外接設備。
與PC機不同,OTG兩用設備的驅動程式棧由USB主機棧和USB設備棧構成以滿足兩種工作模式的需要。OTG驅動程式透過連接器的不同或者是否有HNP交換設備的工作模式來決定使用USB主機棧還是USB設備棧。
當OTG兩用設備以主機模式工作時,USB主機棧工作。其中的主機控制單元驅動程式負責USB主機棧與硬體端點的數據交換,USB驅動程式枚舉並儲存設備的訊息,目標外接設備主機類驅動程式支援目標設備清單裡的設備。主機類驅動程式由晶片製造商提供,同時,OTG提供通用的主機類驅動程式(可以修改以用於非通用設備)。
當OTG兩用設備以從機模式工作時,USB設備棧工作。其中的設備控制單元驅動程式負責USB設備棧與硬體端點的數據交換,USB協議層負責處理USB協議規範,設備類驅動程式的功能取決於該兩用設備的功能(如數碼照相機、存儲設備、印表機等)。
OTG驅動程式負責處理兩用OTG設備的工作模式轉換,同時,它還可以返回其結果(如設備是否支援HNP)並處理匯流排錯誤。應用層程式透過OTG驅動程式開始或者結束一個傳輸事務,透過USB主機棧或設備棧與硬體層交換數據。
5數據流模型
OTG主機和設備被劃分為功能層、USB設備層和USB界面層三個不同的層次。
USB界面層為OTG主機和OTG設備提供物理連接,USB系統軟體使用主機控制單元來管理主機與USB設備的數據傳輸。USB系統軟體相對於主機控制單元而言,處理的是以客戶角度觀察的數據傳輸及客戶與設備的交互。USB設備層為USB主機系統軟體提供一個可用的邏輯設備。主機透過與之功能匹配的客戶軟體實現其各種功能。
OTG設備與以往的USB設備一樣由兩種通道︰數據流通道和消息通道。數據流通道沒有定義好的架構,而消息通道則有固定的架構。但是,每個通道都有一定的帶寬、傳輸類型、傳輸方向和緩沖區大小。自供電設備配置一個預設的控制通道,由它提供該設備的配置和狀態等訊息。
USBOTG規範是USB2。0規範的補充而不是替代品。PC主機和標準外接設備並沒有被取代,因為新的OTG僅適用於需要具有主機功能和更小體積的便攜式設備。OTG在這些外接設備間引入了點對點的(point-to-point)通信模式,這使得便攜式儀器的發展有了更加廣闊的空間。USBOTG已受到Cypress等晶片供應商、軟體開發商和設備製造商的廣泛支援,OTG不久將會成為新一代的"移動計算"解決方案。
6 USB OTG 設備的功能
USB OTG 定義了兩種設備類型:雙角色設備DRD 和單外部設備(Peripheral-OnlyDevice,簡稱為POD)。DRD 具備Host 和外接設備的兩種功能,POD 基本與外接設備功能近似,因此,我們這裏著重討論DRD。
要成為一個USB Host,必須具有存儲外接設備驅動程式、提供足夠的USB 埠電流和A型Host 插座的能力。而其所要實現的基本功能包括3 部分:
管理和控制匯流排,包括提供USB 埠電源管理;
檢測外接設備的接入和斷開,枚舉(Enumerate)設備;
初始化匯流排上所有的資料包傳輸等活動。
同樣,USB 外接設備也具有特定的功能:
響應USB Host 的命令,執行又Host 發起的發送設備描述符、傳送資料等活動;
遠端喚醒處於掛起(Suspend)狀態的主機;
提供自供電(Self-Powered)電源(如果所需電流大於匯流排能提供的限額,選此項)。
DRD 具有USB Host 和外接設備的雙重功能,但是,正因為具有了雙重的角色任務,DRD又必須有切換角色等新的任務和功能,因此,我們可以用(1)式來簡單的定義OTG DRD的功能:
( ) 1 Other Peripheral L L + + = Host DRD
由(1)式可知,完整的USB OTG DRD 還必須具有除了通常的Host 和外接設備之外的一些功能,當然DRD 的Host 功能是有限的,不要求完全實現PC Host 的功能,不過,這正符合了嵌入式領域中對USB 靈活性和便攜性的要求:
作為外接設備,支援12Mbps 的全速模式(或者是480Mbps 的高速模式);
作為Host,也支援全速模式(或者是低速和高速模式);
產生目標外接設備列表(Targeted Peripheral List,簡寫為TPL);
會話請求協定(Session Request Protocol,簡寫為SRP);
主機交流協定(Host Negotiation Protocol,簡寫為HNP);
有且僅有1 個Mini-AB 插座;
至少為匯流排提供8mA 的電流;
能及時將匯流排活動狀態通知給設備用戶。
7 USB OTG 體系的軟體描述
7.1 OTG 配置描述符
在OTG 系統處於枚舉過程時,A 設備就會發送GetDescriptor 命令給B 設備(開始處於外接設備狀態的設備),要求B 設備發送OTG 配置描述符。配置描述符包括3 個位元組,分別是bLength、bDescriptorType 和bmAttributes。
7.2 會話請求協定(Session Request Protocol,簡寫為SRP)
SRP 用於B 設備向A 設備請求建立會話和使用匯流排。
一般,OTG 系統中的A 設備採用的是電池供電,因為這些設備是攜帶型和可移動的,這就決定了,OTG 系統電源管理是非常重要的一個專題。因此,為了節省OTG 系統的電源開支,OTG 2.0 規定A 設備在沒有匯流排活動的時候,可以關掉VBus 上的電源。這樣,當一個B 設備連接到A 設備上之後,就要初始化SRP,併發送給A 設備,請求A 設備在VBus上提供電流支援,進而進行通信。OTG 中,DRD 可以作為A 設備,也可以作為B 設備,
因此,DRD 必須支持初始化SRP 和回應SRP;POD 只能作B 設備,所以,只能初始化SRP。SRP 中,B 設備有兩種方式可以向A 設備發送請求,要求建立SRP:一種是資料線脈沖(Data-Line Pulsing),一種是VBus 脈衝(VBus Pulsing)。
具體的脈衝方法在OTG 2.0 中有詳細的說明。任何一個A 設備只要求能回應一種SRP 方式,而B 設備必須能初始化兩種SRP方式。這樣,當B 設備先初始化一種SRP,而A 設備無法回應是,則B 設備就要用另一種SRP 方式。
7.3 主機交流協定(Host Negotiation Protocol,簡寫為HNP)
HNP 用於初始B 設備與初始A 設備之間切換Host 角色。
OTG DRD 具有Mini AB 型插座,因此,DRD 既可作為Host,也可以作為外接設備。而在
某一個OTG 連接中,這個DRD 到底是作Host(即A 設備),還是作外接設備(即B 設備),則
要根據接入的另一個OTG 設備來定。如果,接入的是OTG POD,那麼,毫無疑問,這個
DRD 肯定是作A 設備。但,如果接入的是另一個DRD,那麼這兩個DRD 之間,就可以HNP
來隨時切換Host 角色。
一次完整的HNP 流程是這樣的:B 設備希望控制匯流排,成為Host;在A 設備發送了SetFeature 命令後,B 設備就可以來請求控制匯流排;A 設備掛起匯流排,通知B 設備可以控制匯流排;B 設備發送信號,斷開與A 設備的連接;A 設備啟動D+信號線上的上拉電阻,將D+置高;這樣,A 設備就開始作為外接設備,放棄了匯流排的控制權,B 設備成為了Host;在B設備完成了對匯流排的控制,就需要上拉其上的D+電阻,放棄匯流排控制權。
當然,這一系列的HNP 活動,不僅僅是通過信號線上的電平變化來實現的。電平變化只是一種標誌,真正內部對匯流排的控制權的變化,則要通過軟體來實現。
7.4 OTG 的軟體結構
OTG 的軟體結構包括3 部分:
OTG 系統硬體驅動:包括SRP 和HNP;
OTG 系統外接設備軟體:實現標準的USB 類,來實現特定的USB 外接設備功能;
OTG 系統Host 軟體:包括Host 驅動程式、作業系統支援軟體、支援外接設備的類庫。
(繼續閱讀...)
文章標籤

立你斯 發表在 痞客邦 留言(0) 人氣(4,763)

  • 個人分類:各種規格
▲top
  • 4月 26 週四 200700:26
  • LINUX-USB驅動程式 啟動 移除 流程

LINUX-USB 啟動 移除 流程
USB 啟動 移除 流程
0.先告訴usb core 驅動程式有支援有哪些裝置

如下 id table
/* table of devices that work with this driver */
static struct usb_device_id skel_table [] = {
{ USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) },
{ }
/* Terminating entry */
};
你必須使用下列巨集讓 user-space能判別驅動程式所支援的裝置
對於usb裝置而言,巨集的第一個參數需為'usb' 字串

MODULE_DEVICE_TABLE (usb, skel_table);

usb core 利用這個結構去得知驅動程式所支援的裝置id
此結構定義在
include/linux/mod_devicetable.h
1.掛載 modprobe

ex:
modprobe skel size=vga fps=30 power_save=0 compression=0 trace=0xff dev_hint=0
後面接的是要傳給 初始函式的參數
上面範例 將會呼叫 usb_skel_init 函式去註冊usb裝置
所有 USB 驅動程式必須建立的主要架構是 struct usb_driver. 這個結構必須被 USB 驅動程式填充並且包含多個函數作業方法和變數, 來向 USB core程式碼描述 USB 驅動程式:
為建立一個值 struct usb_driver 架構, 只有 5 個成員需要被初始化:
static struct usb_driver skel_driver = {
.owner = THIS_MODULE,
.name = "skeleton",
.id_table = skel_table,
.probe = skel_probe,
.disconnect = skel_disconnect,
};
為註冊 struct usb_driver 到 USB core, 一個呼叫 usb_register_driver 帶一個指向 struct usb_driver 的指標. 傳統上在 USB 驅動程式的模組初始化程式碼:
static int __init usb_skel_init(void)
{
int result; /* register this driver with the USB subsystem */
result = usb_register( skel_driver);
if (result)
err("usb_register failed. Error number %d", result);
return result;
}
2. 插入USB 偵測裝置
當使用者安插新的usb裝置時呼叫 .probe 作業方法
如下
static int usb_skel_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
1.檢查新裝置是否支援
2.初始化任何管理USB裝置所需的任何私有結構
3.將裝置相關訊息存入私有結構 usb_set_intfdata(interface, dev);
4.向usb core 註冊一個裝置 usb_register_dev(interface, &skel_class);
}
/* save our data pointer in this interface device */
usb_set_intfdata(interface, dev);
這個函數接受一個指向任何數據類型的指標, 並且儲存它到 struct usb_interface 架構為後面的存取
usb_register_dev 函數要求一個指向 struct usb_interface 的指標和指向 struct usb_class_driver 的指標.
struct usb_class_driver 用來定義許多不同的參數, 當註冊一個次編號USB 驅動程式要 USB core知道這些參數.
這個結構包括下列變數:.
struct usb_class_driver {
char *name;
const struct file_operations *fops;
int minor_base;
};
若為特殊裝置 如video 則用 video_register_device
static struct file_operations skel_fops = {
.owner = THIS_MODULE,
.open = skel_video_open,
.release = skel_video_close,
.read = skel_video_read,
.poll = skel_video_poll,
.mmap = skel_video_mmap,
.ioctl = skel_video_ioctl,
.llseek = no_llseek,
};
static struct video_device skel_template = {
.owner = THIS_MODULE,
.name = " Webcam", /* Filled in later */
.type = VID_TYPE_CAPTURE,
.hardware = VID_HARDWARE_skel,
.release = video_device_release,
.fops = &skel_fops,
.minor = -1,
};
i = video_register_device(skel_template, VFL_TYPE_GRABBER, video_nr);
 
3.開啟AP
EX:
xawtv -geometry 320x240
open
static int skel_video_open(struct inode *inode, struct file *file)
{
1.初始目標裝置 暫存器
2.配置記憶體與參數
3.配置urb
struct urb *usb_alloc_urb(int iso_packets, int mem_flags);
唯一可產生 urb 的函式
輸入參數 第一個 iso_packets 為 iso封包數 ,若你建立的不是iso 的傳輸 則設為0
......................二個 mem_flags 與用來配置核心記憶體 kmalloc() 函式的旗標是相同的
4.初始urb 剛建好的urb 必須先初始好才能給 usb core 使用
usb_fill_int_urb ()
usb_fill_bulk_urb
usb_fill_control_urb

iso urb 需自行初始
5.提交urb - 當提交給 usb core 後就不應該存取 urb 的任何欄位 直到完工函式被呼叫為止
usb_submit_urb

}


iso urb 初始範例

urb->dev = dev;
urb->context = uvd;
urb->pipe = usb_rcvisocpipe(dev, uvd->video_endp-1);
urb->interval = 1;
urb->transfer_flags = URB_ISO_ASAP;
urb->transfer_buffer = cam->sts_buf[i];
urb->complete = konicawc_isoc_irq;
urb->number_of_packets = FRAMES_PER_DESC;
urb->transfer_buffer_length = FRAMES_PER_DESC;
for (j=0; j < FRAMES_PER_DESC; j++)
{
urb->iso_frame_desc[j].offset = j;
urb->iso_frame_desc[j].length = 1;
}
完工函式 complete
如果對 usb_submit_urb 的呼叫成功, 傳遞對 urb 的控制給 USB core, 這個函數返回 0; 否則, 一個負錯誤值被返回. 如果函數成功, urb 的完成處理者(如同被完成函數指標指定的)被確切地呼叫一次, 當 urb 被完成. 立即呼叫urb 內的 complete 指標所指向完工函式並獲得urb 的控制權
 
4.關閉AP
.release = close

static int skel_video_close(struct inode *inode, struct file *file)
當驅動程式需要撤銷以提交給 usb core 的 urb 時 可用 下列兩個之一

int usb_kill_urb(struct urb *urb);
int usb_unlink_urb(struct urb *urb);

 
5.斷開USB
當usb core認為驅動程式以不再需要控制目標裝置時 會呼叫 disconnect 去執行一些收尾的動作
如下
static void usb_skel_disconnect(struct usb_interface *intf)
{
1.取回之前呼叫 usb_set_intfdata 所設定的數據
2.設定數據指標在 struct us_interface 架構為 NULL 來阻止在不正確存取
3.遞減使用次數
}
 
6.卸載模組
ex:
modprobe -r skel
如上指令
卸載usb驅動程式必須使用 usb_deregister() 向核心註銷 struct usb_driver
呼叫
static void __exit usb_skel_exit(void)
{
/* deregister this driver with the USB subsystem */
usb_deregister( skel_driver);
}
(繼續閱讀...)
文章標籤

立你斯 發表在 痞客邦 留言(0) 人氣(3,302)

  • 個人分類:USB
▲top
  • 4月 26 週四 200700:25
  • LINUX-tool-chain 簡介


LINUX-tool-chain 簡介
tool-chain
 
Part 1 – Introduction to GNU C/C++ compiler and binutils
Step 1: understand GNU binutils
The GNU Binutils are a collection of binary tools. The main ones are:
--ld - the GNU linker.
--as - the GNU assembler.
But they also include:
  • addr2line: 可將內含除錯資訊的程式中某個特定位址轉換為其原始程式碼的檔名以 及行號,其功能有點像除錯器 。


  • ar: 可將許多檔案打包成一個單一包裹檔案,同時也可以進行包裹檔的修改、資料 節取、刪除 .... 等等的管理工作。它最常被拿來製作靜態函式庫 (static library),也就是將原始程式碼經由編譯器編譯出一個個目的檔後,就可以 使用 ar 程式將這些目的檔全部打包起來,而這個打包出來的檔案就是一個 靜態函式庫,通常其副檔案即為 .a。


  • c++filt: 由於 C++ 語言可以藉由函式 overload 的方式,讓許多不同的函式使用 相同的函式名,而這些不同的函式在編譯過後就以不同的組合標記 (assembly label) 來表示,此對應過程稱之為 mangling。而工具程式 c++filt 所做的 卻是相反的動作: 它可以由組合標記反向對應出其原來的函式名稱,以便連結 器參考使用,而此反向過程即稱之為 demangling。


  • gprof: 用來顯示程式的效率測試資訊 (profiling)。通常在我們要試圖提升程式的 執行效能時,我們必須要先知道程式的各部分到底花了多少時間來執行,如此 我們心裡才能有個底,知道應該由那些部分先下手改進。然而,光從程式碼本 身有時候很難評估到底那個部分最花時間,這時就可以靠這個工具程式幫忙了。 在測示前,首先必須在程式編譯時加入效率測試資訊 (以 GCC 為例,編譯時必 須加入 -pg 的參數),之後當我們執行程式之後,就會跑出一個 gmon.out 的 檔案,該檔案即內含了效率測試的結果,但它的格式是不可讀的,這時就必須 用 gprof 將它讀出來。


  • nlmconv: 此工具程式可以將目的檔轉換成 NLM (NetWare Loadable Module) 的格式。


  • nm: 此工具程式可以列出目的檔或函式庫中內含的物件名稱,包括所有的函式名稱與 全域變數的名稱 .... 等。


  • objcopy: 此工具程式可以拷備、轉換不同格式的目的檔。


  • objdump: 此工具程式可以列出目的檔內含的資訊。


  • ranlib: 此工具程式可以產生包裹檔的內容索引,並加入該包裹檔中。此包裹檔即為 ar 程式所產生的包裹檔。通常在產生靜態函式庫時需要用到它。等同 ar-s


  • readelf: 此工具程式可以顯示 ELF 格式的目的檔內含的資訊。
    相關用法 請參考 ELF 之 Program Loading 教學文件


  • size: 此工具程式可以列出目的檔或包裹檔中各節區的大小。


  • strings: 此工具程式可以列出檔案中任何可印出的字串。


  • strip: 此工具程式可以將目的檔或可執行檔中不必要的標記與資訊抽離,讓該目的 檔或可執行檔的大小縮小。這些可抽離的資訊通常是除錯資訊以及其他的符號 標記。

  • 14. as 編譯由gcc所輸出的彙編檔(*.s) 產生目標檔(*.o)
    ex: gcc -S hello.c ==> hello.s
    as -o hello.o hello.s ==> hello.o
    效果等同 gcc -c hello.c
     
    Binutils 已經被移植到許多不同的硬體平台上,它同時也具有易於移植到其他平
    台的特性,因此,非常適合用於嵌入式系統的開發。
    Step 2: understand GNU C/C++ compiler (GCC)
    GNU 有許多成名之作,其中最重要的軟體之一就是GCC,GCC 最早由Richard
    Stallman 所發展,因為它是免費使用且原始碼公開,所以發展的相當迅速,很快
    就有許多人將它移植到不同的平台上。GCC 廣受歡迎的另一個原因是它所編譯
    出來的程式碼的品質(程式碼的正確性、大小、執行速度等等)並不比一些其他
    的商用編譯器來的差,有時甚至比較好,因此常常看到許多平台上都有GCC 的
    蹤影。
    GCC 提供一套方便的機制,使你可以很容易的將它移植到另一個平台,同時也
    可以利用它來做為其他語言的前端,到目前為止,它所支援的程式語言有C、
    C++、Objective C、Fortran、Java、Pascal、Ada、Modula-3、Java 等等。選擇
    GCC 來開發compiler,是因為它免費可以取得,同時又支援許多平台和處理器,
    它結構化的設計使得我們可以很容易將它移植到另一個平台上,符合我們快速產
    生目的程式碼的需求,下圖顯示GCC 的內部架構。
    在GCC 的編譯過程中,Parsing 負責分析輸入的原始程式產生Parsing tree,透過
    Tree traveling 產生中間碼RTL(register transfer language),接著GCC 讀取
    Machine Description 利用pattern match 的方式去match RTL 藉此產生assembler
    code,在此過程中,GCC 會使用不同的最佳化方法去最佳化RTL 和產生
    assembler code。
    Step 3: cross toolchains
    由於嵌入式系統先天上的限制(有限的記憶體大小、處理器的效能、系統可能沒
    有螢幕顯示相關訊息等等),在嵌入式系統內執行compiler、assembler 等開發工
    具有時是不可能的。因此,軟體開發工具必須能提供跨平台編譯的功能,才能符
    合實際的需求。
    Cross toolchains 有幾個專有名詞,必須瞭解:
    --Build machine:the machine builds cross toolchains
    --Host machine:the machine cross toolchains will execute on
    --Target machine:the machine cross toolchains will produce outputs for
    GNU toolchains 使用三個欄位(CPU type–Company name–System type)來設定
    machine:
    --CPU type
    --Company name
    --System type
    --For example:vax-dec-ultrix4.2、i386-redhat-linux、m68k-coff、arm-elf

    Step 4: cross newlib

    在撰寫程式的過程中,通常都會使用C standard library,GNU newlib project 提供
    了適用於嵌入式系統的C standard library,讓整個發展環境更為完整。
    Part 2 – Build cross binutils to arm linux
    直接抓arm linux toolchain 檔 解壓
    arm-linux-toolchain.tgz
    tar -zxvf arm-linux-toolchain.tgz
    mv $PWD/arm /usr/local/arm
    再增加 PATH
    PATH=$PATH:/usr/local/arm/2.95.3/bin
    Part 3 – Build cross binutils to FC6
    Step 1 下載GCC及Binutils的原始碼
    GCC :
    ftp://ftp.nctu.edu.tw/computer-languages/C/gcc/releases/gcc-3.4.3/gcc-3.4.3.tar.gz
    Binutils :
    ftp://ftp.nctu.edu.tw/UNIX/gnu/binutils/binutils-2.14.tar.gz
    Newlib :
    ftp://sources.redhat.com/pub/newlib/newlib-1.13.0.tar.gz
    Step 2 設定環境變數及建立暫存目錄
    $ cd
    $ mkdir build-binutils
    $ mkdir build-gcc
    $ mkdir build-newlib
    $ mkdir install
    $ export TARGET=arm-elf
    $ export PREFIX=`pwd`/install
    $ export PATH=$PATH:$PREFIX/bin
    Step 3 安裝binutils
    (1) 將binutils-2.14.tar.gz解壓縮。
    $ tar zxvf binutils-2.14.tar.gz
    (2) 編譯binutils。
    $ cd build-binutils
    $ ../binutils-2.14/configure --target=$TARGET --prefix=$PREFIX
    $ make all install
    $ cd ..
    Step 4 安裝bootstrap GCC (用來編譯newlib)
    (1) 將gcc-3.4.3.tar.gz解壓縮
    $ tar zxvf gcc-3.4.3.tar.gz
    (2) 編譯gcc
    $ cd build-gcc
    $ ../gcc-3.4.3/configure --target=$TARGET --prefix=$PREFIX \
    --with-newlib --without-headers --with-gnu-as \
    --with-gnu-ld --disable-shared --enable-languages=c
    $ make all-gcc install
    $ cd ..
    Step 5 安裝newlib C runtime library
    (1) 編譯newlib
    $ cd build-newlib
    $ ../newlib-1.13.0/configure --target=$TARGET --prefix=$PREFIX
    $ make all install
    $ cd ..
    Step 6 安裝完整的Cross compiler
    (1) 清空暫存目錄
    $ cd build-gcc
    $ rm -rf *
    (2) 編譯compiler
    $ ../gcc-3.4.3/configure --target=$TARGET –prefix=$PREFIX \
    --with-gnu-as --with-gnu-ld --enable-languages=c
    $ make all install
    $ cd
    或者你可以直接用yum安裝
    yum search binutils
    binutils.i386 2.17.50.0.6-2.fc6 installed
    Matched from:
    binutils
    Binutils 是套 binary 的工具,包含了 ar (用來
    建立,修改以及從 archives 中擷取),as (GNU
    assemblers 的家族之一),gprof (用來顯示 call graph 的檔案資料),ld
    (GNU linker),nm (用來從物件檔案列出符號),objcopy (用來
    複製與編譯物件檔案),objdump (用來顯示
    物件檔案的資訊),ranlib (用來產生一個 archive 內容的
    索引),size (用來列出一個物件或 archive 檔案的
    區段大小),strings (用來列出檔案中可列印的
    字串),strip (用來拋棄符號) 與 addr2line (用來轉換
    位址為檔案與行列)。
    若沒安裝 直接 yum install binutils.i386
    yum search gcc
    gcc.i386 4.1.1-51.fc6 installed
    Matched from:
    gcc
    這個 gcc 套件包含了 GNU Compiler Collection verion 4.1。
    要編譯 C 語言程式碼,您需要這個套件
    若沒安裝 直接 yum install gcc.i386
    (繼續閱讀...)
    文章標籤

    立你斯 發表在 痞客邦 留言(0) 人氣(7,758)

    • 個人分類:tool chain
    ▲top
    • 4月 26 週四 200700:24
    • LINUX-U-Boot簡介

    LINUX-U-Boot簡介
    1 U-Boot簡介

    1.1 U-Boot
    全稱Universal Boot Loader,是遵循GPL條款的開放源碼項目。從FADSROM、8xxROM、PPCBOOT逐步發展演化而來。其源碼目錄、編譯形式與Linux內核很相似,事實上,不少U-Boot源碼就是相應的Linux內核源程式的簡化,尤其是一些設備的驅動程式,這從U-Boot源碼的註釋中能體現這一點。但是U-Boot不僅僅支援嵌入式Linux系統的引導,當前,它還支援NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS嵌入式作業系統。
    其目前要支援的目標作業系統是OpenBSD, NetBSD, FreeBSD,4.4BSD, Linux, SVR4, Esix, Solaris, Irix, SCO, Dell, NCR, VxWorks, LynxOS, pSOS, QNX, RTEMS, ARTOS。這是U-Boot中Universal的一層含義,另外一層含義則是U-Boot除了支援PowerPC系列的處理器外,還能支援MIPS、x86、ARM、NIOS、XScale等諸多常用系列的處理器。這兩個特點正是U-Boot項目的開發目標,即支援儘可能多的嵌入式處理器和嵌入式作業系統。就目前來看,U-Boot對PowerPC系列處理器支援最為豐富,對Linux的支援最完善。其它系列的處理器和作業系統基本是在2002年11月PPCBOOT改名為U-Boot後逐步擴充的。從PPCBOOT向U-Boot的順利過渡,很大程度上歸功於U-Boot的維護人德國DENX軟體工程中心Wolfgang Denk[以下簡稱W.D]本人精湛專業水準和持著不懈的努力。當前,U-Boot項目正在他的領軍之下,眾多有志於開放源碼BOOT LOADER移植工作的嵌入式開發人員正如火如荼地將各個不同系列嵌入式處理器的移植工作不斷展開和深入,以支援更多的嵌入式作業系統的裝載與引導。
    選擇U-Boot的理由︰
    開放源碼;
    支援多種嵌入式作業系統內核,如Linux、NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS;
    支援多個處理器系列,如PowerPC、ARM、x86、MIPS、XScale;
    較高的可靠性和穩定性;
    較高的可靠性和穩定性;
    高度靈活的功能設定,適合U-Boot調試、作業系統不同引導要求、產品發布等;
    豐富的設備驅動源碼,如串口、以太網、SDRAM、FLASH、LCD、NVRAM、EEPROM、RTC、鍵盤等;
    較為豐富的開發調試文檔與強大的網路技術支援;
    1.2 U-BOOT的特點
    U-BOOT支援SCC/FEC以太網、OOTP/TFTP引導、IP和MAC的預置功能,這一點和其它BootLoader(如BLOB和RedBoot等)類似。
    但U-BOOT還具有一些特有的功能。
    線上讀寫Flash、DOC、IDE、IIC、EEROM、RTC,其它的BootLoader根本不支援IDE和DOC的線上讀寫。
    支援串行口kermit和S-record下載代碼,U-BOOT本身的工具可以把ELF32格式的可執行檔案轉換成為 S-record格式,直接從串口下載並執行。
    識別二進製、ELF32、uImage格式的Image,對Linux引導有特別的支援。U-BOOT對Linux 內核進一步封裝為uImage。封裝如下︰
    #{CROSS_COMPILE}-objcopy -O binary -R.note -R.comment -S vmlinux \ linux.bin
    #gzip -9 linux.bin
    #tools/mkimage -A arm -O linux -T kernel -C gzip -a 0xc0008000 -e\
    0xc0008000 -n “Linux-2.4.20” -d linux.bin.gz /tftpboot/uImage
    即在Linux內核鏡像vmLinux前添加了一個特殊的頭,這個頭在include/image.h中定義,包括目標作業系統的種類(比如Linux,VxWorks等)、目標CPU的體系機構(比如ARM、PowerPC等)、映像檔案壓縮類型(比如gzip、bzip2等)、加載位址、入口位址、映像名稱和映像的生成時間。當系統引導時,U-BOOT會對這個檔案頭進行CRC校驗,如果正確,才會跳到內核執行。如下所示︰
    WT-ARM9# bootm 0xc1000000
    ## Checking Image at 0xc100000 ...
    Image Name: Linux-2.4.20
    Created: 2004-07-02 22:10:11 UTC
    Image Type: ARM Linux Kernel Image (gzip compressed)
    Data Size: 550196 Bytes = 537 kB = 0 MB
    Load Address: 0xc0008000
    Entry Point: 0xc0008000
    Verifying Checksum ... OK
    Uncompressing Kernel Image ……… OK
    單任務軟體營運環境。U-BOOT可以動態加載和營運獨立的應用程式,這些獨立的應用程式可以利用U-BOOT控制台的I/O函數、內存申請和中斷服務等。這些應用程式還可以在沒有作業系統的情況下營運,是測試硬體系統很好的工具。
    監控(minitor)命令集︰讀寫I/O,內存,暫存器、內存、外設測試功能等
    腳本語言支援(類似BASH腳本)。利用U-BOOT中的autoscr命令,可以在U-BOOT中營運“腳本”。首先在文本檔案中輸入需要執行的命令,然後用tools/mkimage封裝,然後下載到開發板上,用autoscr執行就可以了。
    編輯如下的腳本example.script。
    echo
    echo Network Configuration:
    echo ----------------------
    echo Target:
    printenv ipaddr hostname
    echo
    echo Server:
    printenv serverip rootpath
    echo
    用tools/mkimage對腳本進行封裝。
    # mkimage -A ARM -O linux -T script -C none -a 0 -e 0 -n "autoscr example script" -d example.script /tftpboot/example.img
    Image Name: autoscr example script
    Created: Wes Sep 8 01:15:02 2004
    Image Type: ARM Linux Script (uncompressed)
    Data Size: 157 Bytes = 0.15 kB = 0.00 MB
    Load Address: 0x00000000
    Entry Point: 0x00000000
    Contents:
    Image 0: 149 Bytes = 0 kB = 0 MB
    在U-BOOT中加載並執行這個腳本。
    WT-ARM9# tftp 100000 /tftpboot/example.img
    ARP broadcast 1
    TFTP from server 10.0.0.2; our IP address is 10.0.0.99
    Filename ’/tftpboot/TQM860L/example.img’.
    Load address: 0x100000
    Loading: #
    done
    Bytes transferred = 221 (dd hex)
    WT-ARM9# autoscr 100000
    ## Executing script at 00100000
    Network Configuration:
    ----------------------
    Target:
    ipaddr=10.0.0.99
    hostname=arm
    Server:
    serverip=10.0.0.2
    rootpath=/nfsroot
    WT-ARM9#
    支援WatchDog、LCD logo和狀態指示功能等。如果系統支援splash screen,U-BOOT啟動時,會把這個圖像顯示到LCD上,給用戶更友好的感覺。
    支援MTD和檔案系統。U-BOOT作為一種強大的BootLoader,它不僅支援MTD,而且可以在MTD基礎上實現多種檔案系統,比如cramfs、fat和jffs2等。
    支援中斷。由於道統的BootLoader都分為stage1和stage2,所以在stage2中添加中斷處理服務十分困難,比如BLOB;而U-BOOT是把兩個部分放到了一起,所以添加中斷服務程式就很方便。
    詳細的開發文檔。由於大多數BootLoader都是開源項目,所以文檔都不是很充分。U-BOOT的維護人員意識到了這個問題,充分記錄了開發文檔,所以它的移植要比BLOB等缺少文檔的BootLoader方便。
    2 U-Boot主要目錄架構
    - board 目標板相關檔案,主要包含SDRAM、FLASH驅動;
    - common 獨立於處理器體系架構的通用代碼,如內存大小探測與故障檢測;
    - cpu 與處理器相關的檔案。如mpc8xx次目錄下含串口、網口、LCD驅動及中斷初始化等檔案;
    - driver 通用設備驅動,如CFI FLASH驅動(目前對INTEL FLASH支援較好)
    - doc U-Boot的說明文檔;
    - examples可在U-Boot下營運的示例程式;如hello_world.c,timer.c;
    - include U-Boot頭檔案;尤其configs次目錄下與目標板相關的配置頭檔案是移植過程中經常要修改的檔案;
    - lib_xxx 處理器體系相關的檔案,如lib_ppc, lib_arm目錄分別包含與PowerPC、ARM體系架構相關的檔案;
    - net 與網路功能相關的檔案目錄,如bootp,nfs,tftp;
    - post 上電自檢檔案目錄。尚有待於進一步完善;
    - rtc RTC驅動程式;
    - tools 用於創建U-Boot S-RECORD和BIN鏡像檔案的工具;
    U-Boot可支援的主要功能清單
    系統引導 支援NFS掛載、RAMDISK(壓縮或非壓縮)形式的根檔案系統
    支援NFS掛載、從FLASH中引導壓縮或非壓縮系統內核;
    基本輔助功能 強大的作業系統界面功能;可靈活設定、傳遞多個關鍵參數給作業系統,適合系統在不同開發階段的調試要求與產品發布,尤對Linux支援最為強勁;
    支援目標板環境參數多種存儲模式,如FLASH、NVRAM、EEPROM;
    CRC32校驗,可校驗FLASH中內核、RAMDISK鏡像檔案是否完好;
    設備驅動 串口、SDRAM、FLASH、以太網、LCD、NVRAM、EEPROM、鍵盤、USB、PCMCIA、PCI、RTC等驅動支援;
    上電自檢功能 SDRAM、FLASH大小自動檢測;SDRAM故障檢測;CPU型號;
    1.U-Boot Versioning
    2.U-boot:

    Das U-Boot(The Universal Boot Loader), 最早是由 Magnus Damm 在 2000 年時加入sourceforge 的一個 open source project: PPCBoot 所開始的, 在 2002 年的時候這個project 支援了 4 個 ARM 的 processor, 因此改名為 Das U-Boot, 目前的 project leader 為Wolfgang Denk
    U-BOOT源代碼目錄架構


    - board 和一些已有開發板有關的檔案,比如Makefile和u-boot.lds等都和具體開發板的硬體和位址分發有關。
    - common 與體系架構無關的檔案,實現各種命令的C檔案
    - cpu CPU相關檔案,其中的次目錄都是以U-BOOT所支援的CPU為名,比如有次目錄arm926ejs、mips、mpc8260和nios等,每個特定的次目錄中都包括cpu.c和interrupt.c,start.S。其中cpu.c初始化CPU、設定指令Cache和數據Cache等
    - 74xx_7xx Files specific to Freescale MPC74xx and 7xx CPUs
    - arm720t Files specific to ARM 720 CPUs
    - arm920t Files specific to ARM 920 CPUs
    - at91rm9200 Files specific to Atmel AT91RM9200 CPU
    - imx Files specific to Freescale MC9328 i.MX CPUs
    - s3c24x0 Files specific to Samsung S3C24X0 CPUs
    - arm925t Files specific to ARM 925 CPUs
    - arm926ejs Files specific to ARM 926 CPUs
    - arm1136 Files specific to ARM 1136 CPUs
    - i386 Files specific to i386 CPUs
    - ixp Files specific to Intel XScale IXP CPUs
    - mcf52x2 Files specific to Freescale ColdFire MCF52x2 CPUs
    - mips Files specific to MIPS CPUs
    - mpc5xx Files specific to Freescale MPC5xx CPUs
    - mpc5xxx Files specific to Freescale MPC5xxx CPUs
    - mpc8xx Files specific to Freescale MPC8xx CPUs
    - mpc8220 Files specific to Freescale MPC8220 CPUs
    - mpc824x Files specific to Freescale MPC824x CPUs
    - mpc8260 Files specific to Freescale MPC8260 CPUs
    - mpc85xx Files specific to Freescale MPC85xx CPUs
    - nios Files specific to Altera NIOS CPUs
    - nios2 Files specific to Altera Nios-II CPUs
    - ppc4xx Files specific to AMCC PowerPC 4xx CPUs
    - pxa Files specific to Intel XScale PXA CPUs
    - s3c44b0 Files specific to Samsung S3C44B0 CPUs
    - sa1100 Files specific to Intel StrongARM SA1100 CPUs
    - disk disk驅動的分區處理代碼
    - doc 文檔
    - drivers 通用設備驅動程式,比如各種網卡、支援CFI的Flash、串口和USB匯流排等。
    - dtt Digital Thermometer and Thermostat drivers
    - examples Example code for standalone applications, etc.
    - include 頭檔案,還有對各種硬體平台支援的彙編檔案,系統的配置檔案和對檔案系統支援的檔案。
    - lib_arm 與ARM體系架構相關的代碼。
    - lib_generic Files generic to all architectures
    - lib_i386 Files generic to i386 architecture
    - lib_m68k Files generic to m68k architecture
    - lib_mips Files generic to MIPS architecture
    - lib_nios Files generic to NIOS architecture
    - lib_ppc Files generic to PowerPC architecture
    - net 與網路有關的代碼,BOOTP協議、TFTP協議、RARP協議和NFS檔案系統的實現。
    - post Power On Self Test
    - rtc Real Time Clock drivers
    - tools 創建S-Record格式檔案 和U-BOOT images的工具。
    3. u-boot 的體系架構
    1) 總體架構
    u-boot 是一個層次式架構。做移植工作的軟體人員應當提供串口驅動(UART Driver),以太網驅動(Ethernet Driver),Flash 驅動(Flash 驅動),USB 驅動(USB Driver)。目前,透過USB 口下載程式顯得不是十分必要,所以暫時沒有移植USB 驅動。驅動層之上是u-boot 的應用,command 透過串口提供人機界面。我們可以使用一些命令做一些常用的工作,比如內存檢視命令md。
    Kermit 應用主要用來支援使用串口透過超級終端下載應用程式。TFTP 則是透過網路模式來下載應用程式,例如uclinux 作業系統。
    2) 內存分佈
    在flash rom 中內存分佈圖ev44b0ii 的flash 大小2M(8bits),現下將0-40000 共256k 作為u-boot 的存儲空間。由於u-boot 中有一些環境變量,例如ip 位址,引導檔案名等,可在命令行透過setenv 配置好,透過saveenv 儲存在40000-50000(共64k)這段空間裡。如果存在儲存好的環境變量,u-boot 引導將直接使用這些環境變量。正如從代碼分析中可以看到,我們會把flash 引導代碼搬移到DRAM 中營運。下圖給出u-boot 的代碼在DRAM中的位置。引導代碼u-boot 將從0x0000 0000 處搬移到0x0C700000 處。特別注意的由於ev44b0ii uclinux 中斷向量程式位址在0x0c00 0000 處,所以不能將程式下載到0x0c00 0000 出,通常下載到0x0c08 0000 處。
     
    4.u-boot系統啟動流程


    1.start.s 結構
    1) 定義入口
    一個可執行的Image 必須有一個入口點並且只能有一個唯一的全域入口,通常這個入口放在Rom(flash)的0x0 位址。例如start.S 中的
    .globl _start
    _start: b reset
    值得注意的是你必須告訴編譯器知道這個入口,這個工作主要是修改連接器腳本檔案(lds)。

    2) 設定異常向量(Exception Vector)
    異常向量表,也可稱為中斷向量表,必須是從0 位址開始,連續的存放。如下面的就包括了複位(reset),未定義處理(undef),軟體中斷(SWI),預去指令錯誤(Pabort),數據錯誤(Dabort),保留,以及IRQ,FIQ 等。
    _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
    3) 初始化CPU 相關的pll,clock,中斷控制暫存器
    依次為關閉watch dog timer,關閉中斷,設定LockTime,PLL(phase lock loop),以及clock。
    4) 初始化記憶體控制單元
    5) 將rom 中的程式複製到RAM 中
    首先利用PC 取得bootloader 在flash 的起始位址,再透過標號之差計算出這個程式代
    碼的大小。這些標號,編譯器會在連接(link)的時候生成正確的分佈的值。取得正
    確訊息後,透過暫存器(r3 到r10)做為複製的中間媒介,將代碼複製到RAM 中。
    6) 初始化堆疊
    進入各種模式設定相應模式的堆疊。
    7) 轉到RAM 中執行
    使用指令ldr,pc,RAM 中C 函數位址就可以轉到RAM 中去執行。

    2.2 stage2 C語言代碼部分
    lib_arm/board.c 中的start armboot是C語言開始的函數,也是整個啟動代碼中C語言的主函數,同時還是整個u-boot(armboot)的主函數,該函數主要完成如下操作︰
    1)調用一系列的初始化函數。
    2)初始化Flash設備。
    3)初始化系統內存分發函數。
    4)如果目標系統擁有NAND設備,則初始化NAND設備。
    5)如果目標系統有顯示設備,則初始化該類設備。
    6)初始化相關網路設備,填寫IP、MAC位址等。
    7)進入命令循環(即整個boot的工作循環),接受用戶從串口輸入的命令,然後進行相應的工作。


    5.Add A New BSP To U-Boot
    5.1.U-Boot Software Configuration
    There are two classes of configuration variables:
    Configuration _OPTIONS_:
    These are selectable by the user and have names beginning with "CONFIG_".
    Configuration _SETTINGS_:
    These depend on the hardware etc. and should not be meddled with if you don't know what you're doing; they have names beginning with "CFG_".
    5.2.
    Method 1:
    Create a new BSP
    Method 2:
    Clone an existing BSP
    Method 3:
    Modify an existing BSP

    找出U-Boot的Entry Point
    觀察linker script file (*.lds)
    使用arm-linux-objdump來看反組譯
    5.3.與移植相關的主要檔案夾有︰
    1)CPU 它的每個子檔案夾裡都有如下檔案︰
    makefile
    config.mk
    cpu.c 處理器相關的代碼
    interrupts.c 中斷處理代碼
    serial.c 串口初始化代碼
    start.s 全局開始啟動代碼
    2)BOARD 它的每個子檔案夾裡都有如下檔案︰
    makefile
    config.mk
    smdk2410.c 板子相關的代碼(以smdk2410為例)
    flash.c Flash操作代碼
    memsetup.s 初始化SDRAM代碼
    u-boot.lad 對應的連接檔案
    3) lib_arm 體系架構下的相關實現代碼,比如memcpy等的組合語言的優化實現。
     
    5.4.以FIC8120為例
    1.board
    新增 /board/evb8120 目錄 -參考 smdk2410 內檔案修改
    /board/evb8120/Makefile 修改OBJ 檔案
    /board/evb8120/config.mk 修改TEXT_BASE
    /board/evb8120/evb8120.c 修改board_init() dram_init()等函式
    /board/evb8120/flash.c 修改flash_init() write_buff()等函式
    /board/evb8120/lowlevel_init.s 記憶體參數配置
    /board/evb8120/bootflah.c 將flash.c 的 flash_print_info() flash_erase() flash_get_size() write_hword()移過來修改 並新增一些函式
    2.makefile
    /Makefile 新增 evb8120_config 選項設定
    3./include/configs
    /include/configs/evb8120.h 參考 smdk2410.h內檔案修改
    4.新增soc
    /cpu/arm920t/makefile 沒改
    /cpu/arm920t/config.mk
    /cpu/arm920t/cpu.c 沒改
    /cpu/arm920t/interrupts.c 沒改
    /cpu/arm920t/start.s 程式入口
    參考 s3c24x0內檔案 改成fic8120
    /cpu/arm920t/fic8120/serial.c 串列配置
    /cpu/arm920t/fic8120/i2c.c
    /cpu/arm920t/fic8120/interrupts.c
    /cpu/arm920t/fic8120/speed.c
    /include/fic8120.h fic8120 暫存器設定檔
    /driver/ftmac100.c 新增 FIC8120 Ethernet
    /driver/ftmac100.h
    /driver/Makefile 將OBJS加上 ftmac100.o
    Build
    Require file:
    u-boot-1.1.4.tar.bz2
    patch-u-boot-1.1.4-sq620db.bz2
    Toolchain:
    arm-linux-toolchain
    Build-flow:
    1. Unpack the source code
    [root@localhost root]# tar –jxvf u-boot-1.1.4.tar.bz2
    2. Patch source code
    [root@localhost root]# cd u-boot-1.1.4
    [root@localhost u-boot-1.1.4]# bzcat ../patch-u-boot-1.1.4-sq620db.bz2 | patch –p1
    3. Configuration u-boot for your target board
    [root@localhost u-boot-1.1.4]# make evb8120_config
    4.Build u-boot to binary file
    [root@localhost u-boot-1.1.4]# make
    5. Finish
    [root@localhost u-boot-1.1.4]# ls u-boot.bin
    (繼續閱讀...)
    文章標籤

    立你斯 發表在 痞客邦 留言(0) 人氣(19,855)

    • 個人分類:u-boot
    ▲top
    «1...6566

    熱門文章

    • (62,123)NAND Flash和NOR Flash的比較
    • (62,022)GPS資料格式
    • (21,582)Linux中Workqueue機制分析
    • (17,736)嵌入式經典面試題 
    • (9,610)C語言測試 想成為嵌入式程序員應知道的0x10個基本問題
    • (8,537)MISRA--作為工業標準的C編程規範(1)
    • (6,374)[WII]Homebrew Channel的由來、作用、檔案義意
    • (5,275)[轉載]Linux HAL (Hardware Abstraction Layer)的工作原理
    • (3,371)Platform_device 和 Platform_driver
    • (2,697)GCC 4.6 warning: variable set but not used

    文章分類

    toggle 程式語言 (17)
    • openCL (2)
    • C++ (1)
    • 8051 (5)
    • GPS (4)
    • BarCode (3)
    • 多媒體 (7)
    • 網路相關 (23)
    • 程式設計 (20)
    • ARM (22)
    • u-boot (19)
    • 各種規格 (41)
    • 程式心得 (34)
    • 程式工具 (18)
    • 版本控制 (13)
    • RTOS (5)
    • uC/OS 筆記 (12)
    • Objective-C (3)
    toggle 其他 (8)
    • SCRATCH (1)
    • 三國風雲 (4)
    • 產業消息 (2)
    • 未分類資料夾 (12)
    • 娛樂 (13)
    • 語文學習 (8)
    • 理財 (7)
    • 幼教 (2)
    toggle Linux Driver (9)
    • PCI (6)
    • driver 教學 (17)
    • driver 問題修正 (11)
    • 嵌入式 driver 相關 (10)
    • USB (8)
    • I2C (7)
    • V4L2 (8)
    • Driver 其他 (29)
    • Alsa (15)
    toggle Linux (19)
    • yocto (4)
    • WIFI (14)
    • GUI (10)
    • CentOS (4)
    • Linux system programming (8)
    • 工作使用 (2)
    • 模擬-VM (3)
    • 編譯相關 (26)
    • tslib (9)
    • 檔案系統 (18)
    • 嵌入式相關 (10)
    • 系統相關 (21)
    • LINUX (57)
    • 模擬-colinux (6)
    • 模擬-cygwin (10)
    • Android (21)
    • Mplayer (11)
    • tool chain (6)
    • 系統指令 (6)
    • NV (1)
    • 未分類文章 (1)

    最新文章

    • C語言學習
    • Could not resolve host: source.codeaurora.org
    • NVIDIA_Jetson_ISP (ORIN)
    • AP6275S 相關
    • rtl8822cs 相關
    • LINUX 解決package ~ is not configured yet
    • Ubuntu 22.04 安裝 VMWare 16.2.3 後無法啟動
    • How To Access Your Google Drive on Ubuntu
    • xinput
    • gsettings 取得 KEY 值

    文章精選

    文章搜尋

    最新留言

    • [25/05/01] 訪客 於文章「NVIDIA_Jetson_ISP (O...」留言:
      您好!有什麼我可以幫忙的嗎? 我是工程師 也可以看看我的...
    • [22/02/11] lynn770707 於文章「Linux GPIO Driver Gu...」留言:
      這篇記錄幫了我大忙~感謝小藍XDDDD...
    • [16/09/05] Scron Pen 於文章「使用變數型別的良好習慣...」留言:
      感謝,豁然開朗,受益良多~...
    • [12/02/05] 恰吉 於文章「Android X86版體驗...」留言:
      請問一下~安裝的時候找不到硬碟就沒辦法了嗎~ 發現IDE硬碟...
    • [11/12/01] cwhuang 於文章「Android X86版體驗...」留言:
      前面的說明有些錯誤。Google Android 平台從未正...
    • [11/07/14] *香甜水蜜桃* 於文章「alsa(Advanced Linux ...」留言:
      <p>我可以挖角你嘛?</p> <p>對不起~看到你的文章我...
    • [11/05/31] Mr.Kenny™ 於文章「Android X86版體驗...」留言:
      如果下載最近的Android source來編譯,可能會發現...
    • [11/05/11] love521025 於文章「Android 軟件安裝程序(*.apk...」留言:
      請問~<div> 我在網路上有看到有人開發出來的一個Andr...
    • [11/03/17] 立你斯 於文章「CCIR656 - BT.656...」留言:
      <p><font style="BORDER-BOTTOM:...
    • [10/11/25] 立你斯 於文章「Linux kernel 版本不包含GI...」留言:
      <p><span style="FONT-FAMILY:宋体...

    參觀人氣

    • 本日人氣:
    • 累積人氣:

    個人資訊

    立你斯
    暱稱:
    立你斯
    分類:
    數位生活
    好友:
    累積中
    地區:

    誰來我家