之前看別人的程式,看到作者在ROMFS實作時把資料轉成object檔案,然後在C語言中直接存取資料。他的作法是
- 寫一個host程式,將某個目錄下面的檔案和目錄轉成單一個binary
- 將這個binary轉成object檔案
- 更改link script,讓最後的binary可以存取object檔案的section
這個project使ARM的架構Realtime 作業系統。看完手癢也想看看Linux下面要怎麼做到類似的功能。本來想說是不是要動到link script,後來看到這邊的參考資料後,發現只要存取symbol就可以使用了。克服這個問題後就可以來寫個小程式驗證一下。
首先我們先弄個測試資料,很簡單就是一個數字顯示後面字串長度後再存放字串。
1
|
|
接下來就是Makefile部份
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
Makefile說明:
* patsubst
* Makefile 提供的函數,用在pattern 替換,所以上面做了下列的代換
* test_obj轉成test_obj.o
* $@
* Makefile的內建巨集,代表target
* $^
* Makefile的內建巨集,代表prerequisite
重點是把資料檔案轉成object的部份,節錄該部份並說明如下
objcopy -I binary -O $(BFN) -B $(ARCH) --prefix-sections '.mydata' $^ $@
-I binary
- 指定input檔案binary格式為binary
-O elf64-x86-64
- 指定output binary 格式為elf64-x86-64
-B i386
- 指定架構為i386
--prefix-sections '.mydata'
- 指定放在.mydata的section
至於要怎麼知道binary格式和架構呢?您可以用objcopy --info |less
配合file test_obj.o
找出平台上的參數。
我們先來看一下section是不是真的放到.mydata?
1 2 3 4 5 6 7 8 |
|
我只知道.mydata的section,裏面的資訊目前還不清楚有什麼意義。
我們再用nm來看檔案內有哪些symbol
1 2 3 4 |
|
flag說明
* D
* 資料放在初始的資料section
* A
* Symbol的值已固定,之後link也不會更動。目前還不知道這樣透露出有什麼額外的資訊
接下來就是存取的方式了,測試程式如下。主要就是從section讀出字串再印出來。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
程式說明如下
* 前面nm看到的symbol _binary_my_data_txt_end
, _binary_my_data_txt_start
, 和_binary_my_data_txt_size
只是一個sybmol,這邊我們存的是字元所以宣告成char
* _binary_my_data_txt_start存放的是該section開始的資料,我們可以用gdb驗證一下
1 2 3 4 |
|
- 所以我們可以取得該資料位址後,讀出字串長度後,再複製後面的字串並列印出來。
最後執行結果如下
1 2 |
|