lds檔案用於指定程式鏈結時的不同段內容的位置安排。linux核心映象裡就是利用lds檔案,把不同的內容劃分成很多不同的段.
uboot裡的命令也就是利用此功能,把所有的命令統一到乙個段裡.
arm-linux-gnueabihf-ld –verbose > test.lds //把編譯器預設的鏈結指令碼輸出到test.lds裡
修改test.lds, 把最前的6行刪除掉, 也要刪除最後一行.
在84行加入自己的段:
__mysection_start = . ;
.mysection :
.align = 4
; __mysection_end = . ;
// __mysection_start 和 __mysection_end用於記錄段的開始位址與結束位址.
*(.mysection) 表示所有的.o檔案的.mysection段內容集中放起來
在**裡指定變數是分配在.mysection段:
int num __attribute__ ((section(".mysection"))) = 1;
int num2 __attribute__ ((section(".mysection"))) = 2;
int num3 __attribute__ ((section(".mysection"))) = 3;
編譯時指定使用test.lds鏈結指令碼:
arm-linux
-gnueabihf
-gcc test.c -ttest
.lds -o test
編譯完成後,可以反彙編確認.mysection裡的狀況:
arm-linux-gnueabihf-objdump -d test
檢視到的輸出:
disassembly of section .mysection:
000083d4 :
83d4: 00000001 andeq r0, r0, r1
000083d8 :
83d8: 00000002 andeq r0, r0, r2
000083dc :
83dc: 00000003 andeq r0, r0, r3
加進乙個段後, 可以通過__mysection_start 和__mysection_end算出乙個段的大小,及段裡的變數個數.
也可以取出每個段裡變數的值.
在**裡:
__mysection_start 相當於乙個變數(型別不重要),它的位址就是段的開始位址
__mysection_end, 它的位址就是段的結束位址
實驗**:
test.c
#include
int num __attribute__ ((section(".mysection"))) = 1;
int num2 __attribute__ ((section(".mysection"))) = 2;
int num3 __attribute__ ((section(".mysection"))) = 3;
int num4 __attribute__ ((section(".mysection"))) = 55;
extern
int __mysection_start; //這個變數是在鏈結指令碼裡宣告的
extern
int __mysection_end;
int main(void)
return
0; }
以後再加變數到.mysection段裡,main函式的**可以不用修改都可以獲取到相應的變數的值
實現命令的功能:
test.c
#include
typedef
struct cmd_t;
#define mysection __attribute__ ((section(".mysection")))
#define add_cmd(name, help, func) \
cmd_t __cmd_##name mysection =
void do_cmd1(void)
add_cmd(cmd1, "help of cmd1", do_cmd1);
extern cmd_t __mysection_start;
extern cmd_t __mysection_end;
int main(void)
return
0; }
// 再增加命令時,只需實現命令的功能函式後, 呼叫add_cmd巨集即可.
// 也可以把每個命令用乙個原始檔來實現,最後一起編譯即可。uboot裡的命令就是採用這樣的方法.
自定義日誌檔案
借用 部落格 usr bin python coding utf 8 importlogging importos.path importtime 自定義日誌類 classlogger object def init self,logger 指定儲存日誌的檔案路徑,日誌級別,以及呼叫檔案 將日誌存入...
c Attribute與自定義
using system using system.reflection public class demo public class myfieldattributes static void displayfield object obj,fieldinfo f attributes f.nam...
TensorFlow2 0 自定義層與自定義網路
自定義層函式需要繼承layers.layer,自定義網路需要繼承keras.model。其內部需要定義兩個函式 1 init 初始化函式,內部需要定義構造形式 2 call函式,內部需要定義計算形式及返回值。self def layer class mydense layers.layer inhe...