在使用gdb或者其他工具調試默認優化選項的內核時,內核的反彙編代碼與原來的C語言代碼對應很亂。如果切換到C語言模式,使用單步調試時會看到執行順序在C語言源代碼裏面跳來跳去,甚是紊亂。
這一切都是GCC對代碼進行了優化造成的,優化後的代碼執行順序與源代碼的順序就有出入了。GCC優化代碼,提高運行效率與代碼緊湊度,但對於調試學習內核就不友好了。
通過下面的方法去掉內核編譯時的優化。
1,優化級別從-O2改爲-O1
修改內核源代碼根目錄下的Makefile
all: vmlinux
ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
KBUILD_CFLAGS += -Os
else
KBUILD_CFLAGS += -O1
endif
CONFIG_CC_OPTIMIZE_FOR_SIZE默認是不定義的,所以修改紅色部分爲-O1,優化級別爲1級,只做基本的優化。
2,不要將只有一個地方調用的函數自動變爲inline函數
變爲inline函數之後,對於調試代碼極爲不便。原來在裏面定義的局部變量都沒有了,要查看一些局部變量的值時需要從寄存器裏面去推導,並且需要手動的做強制類型轉換才能看到數據結構的值。
禁止inline後會是一次真正的函數調用,對於通過調試理解代碼功能作用很大。
# We trigger additional mismatches with less inlining
ifdef CONFIG_DEBUG_SECTION_MISMATCH
KBUILD_CFLAGS += $(call cc-option, -fno-inline-functions-called-once)
endif
CONFIG_DEBUG_SECTION_MISMATCH這個宏本來是檢測代碼/數據段類型屬性不匹配的,定義後同時有個功能是禁止將只有一個地方調用的函數變爲inline函數。
附:
編譯qemu的ARM vexpress平臺的內核命令:
linux-3.4.70$ make O=/home/dazhi/vexpress/build/kernel ARCH=arm CROSS_COMPILE=arm-linux- vexpress_defconfig menuconfig
linux-3.4.70$ make O=/home/dazhi/vexpress/build/kernel ARCH=arm CROSS_COMPILE=arm-linux-
採用Android工具鏈編譯:
make -C SourceCode/linux-3.4.70/ O=/home/dazhi/linuxbuild/ ARCH=arm CROSS_COMPILE=/home/dazhi/AndroidL/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8/bin/arm-eabi- versatile_defconfig menuconfig
make -C SourceCode/linux-3.4.70/ O=/home/dazhi/linuxbuild/ ARCH=arm CROSS_COMPILE=/home/dazhi/AndroidL/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8/bin/arm-eabi-