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

2011年10月4日 星期二

Uboot 起始點

Uboot裡, code起始點其實要找u-boot.lds
公版是放在/arch/cpu/$cpu_name/ 下

我用這板freescale給的BSP 則放在/board/$vendor_name/$board_name/ 下

在start.o 前面還塞個flash_header.o
start.o 用/cpu/arm_cortex/ 下的start.o
flash_header.S 實在有點看不懂

arm 指令集要研究一下囉
以下轉貼一下 高手研究的結果  原出處連結

對於.lds檔案,它定義了整個程式編譯之後的連接過程,決定了一個可執行程式的各個段的存儲位置。
先看一下GNU官方網站上對.lds檔案形式的完整描述︰
SECTIONS {
...
secname start BLOCK(align) (NOLOAD) : AT ( ldadr )
  { contents } >region :phdr =fill
...
}

secname和contents是必須的,其他的都是可選的。下面挑幾個常用的看看︰
1、secname︰段名
2、contents︰決定哪些內容放在本段,可以是整個目標檔案,也可以是目標檔案中的某段(程式碼段、數據段等)
3、start︰本段連接(執行)的位址,如果沒有使用AT(ldadr),本段存儲的位址也是start。GNU網站上說start可以用任意一種描述位址的符號來描述。
4、AT(ldadr)︰定義本段存儲(加載)的位址。
看一個簡單的例子︰(摘自《2410完全開發》)
/* nand.lds */
SECTIONS {
firtst 0x00000000 : { head.o init.o }
second 0x30000000 : AT(4096) { main.o }
}
以上,
head.o放在0x00000000位址開始處,init.o放在head.o後面,他們的執行位址也是0x00000000,即連接和存儲位址相同(沒有AT指定);
main.o放在4096(0x1000,是AT指定的,存儲位址)開始處,但是它的執行位址在0x30000000,執行之前需要從0x1000(加載處)複製到0x30000000(執行處),此過程也就用到了讀取Nand flash。
這就是存儲位址和連接(執行)位址的不同,稱為加載時域和執行時域,可以在.lds連接腳本檔案中分別指定。
編寫好的.lds檔案,在用arm-linux-ld連接命令時帶-Tfilename來調用執行,如
arm-linux-ld   Tnand.lds x.o y.o   o xy.o。
也用-Ttext參數直接指定連接位址,如
arm-linux-ld   Ttext 0x30000000 x.o y.o   o xy.o。
既然程式有了兩種位址,就涉及到一些跳轉指令的區別
ARM彙編中,常有兩種跳轉方法︰b跳轉指令、ldr指令向PC賦值。我自己經過歸納如下︰
(1)b step1 ︰b跳轉指令是相對跳轉,倚賴當前PC的值,偏移量是透過該指令本身的bit[23:0]算出來的,這使得使用b指令的程式不倚賴於要跳到的程式碼的位置,只看指令本身。
(2)ldr pc, =step1 ︰該指令是從內存中的某個位置(step1)讀出數據並賦給PC,同樣倚賴當前PC的值,但是偏移量是那個位置(step1)的連接位址(執行時的位址),所以可以用它實現從Flash到RAM的程式跳轉。
(3)此外,有必要回味一下adr偽指令,U-boot中那段relocate程式碼就是透過adr實現當前程式是在RAM中還是flash中。仍然用我當時的註釋︰
relocate: /* 把U-Boot重新定位到RAM */
    adr r0, _start /* r0是程式碼的當前位置 */
/* adr偽指令,彙編器自動透過當前PC的值算出 如果執行到_start時PC的值,放到r0中︰
當此段在flash中執行時r0 = _start = 0;
當此段在RAM中執行時_start = _TEXT_BASE(在board/smdk2410/config.mk中指定的值為0x33F80000,即u-boot在把程式碼拷貝到RAM中去執行的程式碼段的開始) */
    ldr r1, _TEXT_BASE /* 測試判斷是從Flash啟動,還是RAM */
/* 此句執行的結果r1始終是0x33FF80000,因為此值是又編譯器指定的(ads中設定,或-D設定編譯器參數) */
    cmp r0, r1 /* 比較r0和r1,調試的時候不要執行重定位 */

    下面,結合u-boot.lds看看一個正式的連接腳本檔案。
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段的結束位置
}

2011年9月30日 星期五

ADB 連結問題排除

搞了半天 HTC hero /adb devices 就是找不到, 我Fujitsu Haro 就是找不到

谷歌了一下

方法一: ~/.android 目錄下建一個adb.ini
加以下內容
----------------------
1 #Vendor ID 總共數量
04c5 #VID

方法二
/etc/udev/rules.d/ 新增一檔案 50-android.rules
內容:

SUBSYSTEM=="usb", ATTRS{idVendor}=="04c5", SYMLINK+="android_adb", MODE="0666", OWNER="<username>"


ADB tools


轉載  
Adb 全名是 Android Debug Bridge,是開發或使用 Android 時很常用到的工具。使用者可以從Android 官方站下載 SDK,在其中的 platform-tools (原本在 \Tools) 中找到。
當機器上有打開 USB debug mode 時,使用者即可通過adb 進行各種 debug 、底層(linux user space)的 Android 功能。比較常用的功能:

- tools\ddms.bat: Android AP/Framework 層最主要的 debug tool
 - 安裝 Android 應用程式
- 連接機器,使用 linux userspace 的功能。 ex: ping, ssh, ftp ... blah blah.
adb的工作方式比較特殊採用監聽Socket TCP 5554等端口的方式讓IDE和Qemu通訊,預設情況下adb會daemon相關的port。

這篇文章主要是整理了一些adb 的基本功能,後面補上一些開發時常用的功能。

文件參考:
- 官方的說明文件: http://developer.android.com/intl/zh-TW/guide/developing/tools/adb.html
Android模擬器adb命令介紹
- Source code: system/core/adb/ ,除了 adb client 跟 adbd (Android 系統內負責處理 adb 功能的 daemon)的實作外,裡面包含了 service 跟 overview 的文件。

功能介紹
1. 通過adb 進入機器或模擬器的shell模式
adb shell
也可以執行各種Linux的命令,其命令格式為:adb shell command
PS: 當 adb shell 之後提示字元為"#"時,表示使用者為 root (最大權限),若是 "$" 則是以shell 權限工作


adb shell ls 就是列出目錄
adb shell dmesg 會列印出Linux kernel log
adb shell cat /proc/kmsg 持續印出 kernel log (需要 root)
adb shell keyevent 1 輸入 keyevent,可輸入的內容參考 adb shell keyevent



2. 安裝Android 應用程式(*.apk)

可執行adb install android123.apk,這樣名為android123的安裝包就會安裝到Android模擬器中,前提是android123.apk文件需要放到SDK\Tools目錄下。
比較特殊的安裝方法還有
"-r": 當已經安裝過舊版本的程式時,可以使用 -r 去覆蓋。
"-f": 強制安裝,通常在安裝程式時會遇到相容問題,可使用此參數解決


3. PC 端與Android 機器的檔案傳輸
除了使用記憶卡模式外,還可使用下面命令可以進行檔案傳輸:
把android123.txt 傳到機器上的/tmp/ 資料夾中:
adb push android123.txt /tmp/android123.txt

從機器上把 android123.txt 抓到PC端:

adb pull /tmp/android123.txt android123.txt

4. 顯示系統資訊 - dumpsys
除了直接輸入 adb shell dumpsys 外,也可以另外指定要顯示的 service,簡列一些參數,用法如:
adb shell dumpsys SurfaceFlinger

battery: 列出基本的電池資訊
batteryinfo: 各種功能使用 power 的狀況,同About Phone 裡面的電池使用狀況。
SurfaceFlinger: 系統的 Surface 使用情況
power: 列出 Power Manager 的參數,如 wakelock 時間等
alarm: 列出目前有註冊 alarm 者

5. 其他
- Android 預設可編譯成三種模式: eng, userdebug, user。一般使用者拿到的機器多是 user 版,當然如果是開發人員,可能會使用 eng 或 userdebug 版 進行debug。或是使用者自行 root 機器後,可使用下列指令取得 root 權限
adb root
- 一般為了防止系統出問題,所以 /system 通常在掛載時會設定為唯讀(read only),當使用者有root權限時,可使用下面指令將系統重新掛載成 R/W 模式,可對 /system 內的檔案做修改
adb remount
- 如果在使用 adb 時發現有* daemon not running. starting it now *的提示可以結束adb
adb kill-server

- 顯示 android 機器連接狀況

adb devices 
結果如下
List of devices attached
1234567890ABCDEF        device

- 等待正在運行的設備
adb wait-for-device
- Port forwarding,在某些應用如模擬器的網路連接使用、VNC時,會用到這項功能。主要是用來將機器上的的TCP port 5555 轉發到 port 1234

adb forward tcp:5555 tcp:1234

- 擷取系統內的各種資訊,產生 bug report 

adb bugreport




Original Post Link