嵌入式系统裸机程序开发与调试
文章目錄
- 🌹1.GUN工具的使用
- 🚀1.1符號顯示器nm
- 💒1.2objdump:信息查看器
- 🎪1.3objcopy:段剪輯器
- ??2.程序編譯過程
- ?2.1程序鏈接過程
- 2.2指定頭文件
- 🎪2.3 指定庫文件
- ?3.裸機開發流程
🌹1.GUN工具的使用
GUN是一個開源的組織,給我們帶來了很多開源軟件和編譯工具,如我們常用的
- C編譯器 :gcc
- 預處理器 :cpp
- C++編譯器 g++
- 匯編器 :as
- 鏈接器 :ld
- 二進制工具集 :objcopy
二進制工具集的含義:他們專門用于控制和將二進制目標代碼從一種格式轉換為另一種格式,這些工具被稱作為objcopy和objdump,許多linux機器使用的底層軟件在編譯階段都非常依賴這些工具。調試的時候也需要他們。objcopy用于從一個文件拷貝目標代碼到另一個文件,并在這個過程中進行轉換。這樣外面可以在不同的目標代碼格式之間進行自動的轉換并操縱這個過程中的內容。他們可以任何方式來操作二進制文件。
🚀1.1符號顯示器nm
可通過arm-linux-gcc -v 查看是否有arm-linux-gcc這個編譯器
顯示符號 $nm -n main_elf
顯示內容:
?第一列為符號地址
?第二列為符號所在段
?第三列為符號名稱
比如我執行arm-linux -nm -n demo,demo是我的一個可執行程序,會出現如下信息
這些符號的含義如下圖所示:
這個符號顯示器很有用,可以看到絕大部分的信息,但是局部變量是看不到的,因為他分配在棧里面
💒1.2objdump:信息查看器
objdump 有點像那個快速查看之類的工具,就是以一種可閱讀的格式讓你更多地了解二進制文件可能帶有的附加信息。對于一般只想讓自己程序跑起來的程序員,這個命令沒有更多意義,對于想進一步了解系統的程序員,應該掌握這種工具,至少你可以自己寫寫shellcode了,或者看看人家給的 exploit 中的 shellcode 是什么東西。
? 查看所有段信息 $objdump -h main_elf
? 查看文件頭信息 $objdump -f main_elf
? 查看反匯編 $objdump -d main_elf
? 查看內嵌反匯編 $objdump -S -d main_elf
我一一演示一遍這些命令的使用
🎪1.3objcopy:段剪輯器
objcopy被用來復制一個目標文件的內容到另一個文件中,可以使用不同于源文件的格式來輸出目的文件,即可以進行格式轉換
去除elf格式信息
$objcopy -O binary -S main_elf main.bin
??2.程序編譯過程
程序編譯4步驟:
(1)預處理
C/C++源文件中,以“#”開頭的命令被稱為預處理命令,如包含命令“#include”、宏定義命令“#define”、條件編譯命令“#if”、“#ifdef”等。預處理就是將要包含(include)的文件插入原文件中、將宏定義展開、根據條件編譯命令選擇要使用的代碼,最后將這些東西輸出到一個“.i”文件中等待進一步處理。
(2)編譯
編譯就是把C/C++代碼(比如上述的“.i”文件)“翻譯”成匯編代碼。
(3)匯編
匯編就是將第二步輸出的匯編代碼翻譯成符合一定格式的機器代碼,在Linux系統上一般表現為ELF目標文件(OBJ文件)。“反匯編”是指將機器代碼轉換為匯編代碼,這在調試程序時常常用到。
(4)鏈接
鏈接就是將上步生成的OBJ文件和系統庫的OBJ文件、庫文件鏈接起來,最終生成了可以在特定平臺運行的可執行文件。
- 一個標準應用程序通常都由鏈接器采用默認鏈接腳本(arm-linux-ld --verbose)將“用戶程序” 和“庫” 共同鏈接生成可執行程序
?2.1程序鏈接過程
鏈接過程中需要一個標號(_start)作為程序入口
標號(_start)的作用是: 將用戶程序從匯編帶到了C語言程序入口, 即main()函數, 從此開始我們的應用程序之旅
2.2指定頭文件
頭文件在哪里?
-
系統目錄
-
系統目錄在哪?工具鏈里的某個include目錄
-
怎么確定?
echo 'main(){}'| gcc -E -v - // 它會列出頭文件目錄、庫目錄(LIBRARY_PATH) -
可以不使用系統include目錄嗎?可以,編譯時指定參數-nostdinc
-
-
可以自己指定頭文件目錄
🎪2.3 指定庫文件
庫文件在哪里?
-
系統目錄
-
系統目錄在哪?工具鏈里的某個lib目錄
-
怎么確定?
echo 'main(){}'| gcc -E -v - // 它會列出頭文件目錄、庫目錄(LIBRARY_PATH) -
可以不使用系統lib目錄嗎?可以,編譯時指定參數-nostdlib
-
-
可以自己指定庫文件目錄
- 指定庫文件
?3.裸機開發流程
*假設你寫了一個程序名字為uart_test.c
使用命令編譯:arm-linux-gcc uart_test.c -c -o uart.o
鏈接并強行指定main入口為0x48000000:arm-none-linux-gnueabi-ld uart.o -o uart-test -e main -Ttext=0x48000000
把elf文件變為bin結尾的二進制文件arm-none-linux-gnueabi-objcopy -O binary -S uart
把生成的.bin結尾的文件放到windows
linux板子終端進入uboot修改環境變量執行setenv loadaddr 0x48000000修改并通過saveenv進行保存,注意環境變量的地址為你強行指定main函數的地址
在uboot敲loadb命令等待文件傳輸
打開超級終端serucecrt把.bin文件傳輸到板子里
通過go 0x48000000 執行main函數,這時一個完整的程序就可以執行了,可以在里面執行最簡單的點燈操作,如下圖所示
總結
以上是生活随笔為你收集整理的嵌入式系统裸机程序开发与调试的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 图片转成pdf下载
- 下一篇: 华旭金卡js调用身份证阅读器和易联众社保