linux内核禁止优化的设置

环境介绍

内核版本:linux-4.15.2
编译器:gcc-arm-10.3-2021.07-x86_64-arm-none-linux-gnueabihf

关闭优化的原因

为了方便调试linux 内核,需要把内核的优化设置从默认的-O2调整为-Og。这里的优化点有很多,不仅仅是修改Makefile 把O2变成Og这么简单,还要修改内核源码。否则编译会报错。

关闭优化的相关操作

准确工作

  • 禁止内核优化,为了是调试时方便,先设置 开启内核调试信息
Kernel hacking  --->
     Compile-time checks and compiler options  ---> 
         [*] Compile the kernel with debug info
  • 设置Makefile 见Makefile 补充
--- raw/linux-4.15.2/Makefile	2018-02-07 11:14:15.000000000 -0800
+++ linux-4.15.2/Makefile	2022-09-15 02:03:35.769800577 -0700
@@ -634,6 +634,10 @@
 KBUILD_CFLAGS	+= $(call cc-disable-warning, format-overflow)
 KBUILD_CFLAGS	+= $(call cc-disable-warning, int-in-bool-context)
 
+ifdef CONFIG_CC_OPTIMIZE_FOR_DEBUGGING
+KBUILD_CFLAGS	+= $(call cc-option, -Og)
+KBUILD_CFLAGS   += $(call cc-disable-warning,maybe-uninitialized,)
+else
 ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
 KBUILD_CFLAGS	+= $(call cc-option,-Oz,-Os)
 KBUILD_CFLAGS	+= $(call cc-disable-warning,maybe-uninitialized,)
@@ -644,6 +648,7 @@
 KBUILD_CFLAGS   += -O2
 endif
 endif
+endif
 
 KBUILD_CFLAGS += $(call cc-ifversion, -lt, 0409, \
 			$(call cc-disable-warning,maybe-uninitialized,))
@@ -751,6 +756,12 @@
 		   $(call cc-option,-fno-var-tracking)
 endif
 
+ifdef CONFIG_NO_AUTO_INLINE
+KBUILD_CFLAGS   += $(call cc-option, -fno-inline-functions) \
+		   $(call cc-option, -fno-inline-small-functions) \
+		   $(call cc-option, -fno-inline-functions-called-once)
+endif
+
 ifdef CONFIG_FUNCTION_TRACER
 ifndef CC_FLAGS_FTRACE
 CC_FLAGS_FTRACE := -pg
  • 设置 /include/linux/compiler-gcc.h
--- raw/linux-4.15.2/include/linux/compiler-gcc.h	2018-02-07 11:14:15.000000000 -0800
+++ linux-4.15.2/include/linux/compiler-gcc.h	2022-09-14 23:19:30.839359338 -0700
@@ -190,7 +190,8 @@
 
 #define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
 
-#ifndef __CHECKER__
+//#ifndef __CHECKER__
+#if !defined(__CHECKER__) && !defined(CONFIG_CC_OPTIMIZE_FOR_DEBUGGING)
 # define __compiletime_warning(message) __attribute__((warning(message)))
 # define __compiletime_error(message) __attribute__((error(message)))
 #endif /* __CHECKER__ */
  • 设置/include/linux/compiler.h
--- raw/linux-4.15.2/include/linux/compiler.h	2018-02-07 11:14:15.000000000 -0800
+++ linux-4.15.2/include/linux/compiler.h	2022-09-14 23:21:12.646884095 -0700
@@ -286,7 +286,8 @@
  * sparse see a constant array size without breaking compiletime_assert on old
  * versions of GCC (e.g. 4.2.4), so hide the array from sparse altogether.
  */
-# ifndef __CHECKER__
+//# ifndef __CHECKER__
+# if !defined(__CHECKER__) && !defined(CONFIG_CC_OPTIMIZE_FOR_DEBUGGING)
 #  define __compiletime_error_fallback(condition) \
 	do { ((void)sizeof(char[1 - 2 * condition])); } while (0)
 # endif
  • 设置/init/Kconfig
--- raw/linux-4.15.2/init/Kconfig	2018-02-07 11:14:15.000000000 -0800
+++ linux-4.15.2/init/Kconfig	2022-09-14 23:32:16.816711523 -0700
@@ -1037,6 +1037,25 @@
 
 	  If unsure, say N.
 
+config CC_OPTIMIZE_FOR_DEBUGGING
+	bool "Optimize for better debugging experience (-Og)"
+	select NO_AUTO_INLINE
+	help
+	  This will apply GCC '-Og' optimization level which is supported
+	  since GCC 4.8. This optimization level offers a reasonable level
+	  of optimization while maintaining fast compilation and a good
+	  debugging experience. It is similar to '-O1' while preferring to
+	  keep debug ability over runtime speed. The overall performance
+	  will drop a bit (~6%).
+
+	  Use only if you want to debug the kernel, especially if you want
+	  to have better kernel debugging experience with gdb facilities
+	  like kgdb or qemu. If enabling this option breaks your kernel,
+	  you should either disable this or find a fix (mostly in the arch
+	  code).
+
+	  If unsure, select N.
+
 endchoice
 
 config SYSCTL
  • 设置/arch/arm/mm/mmu.c (解决编译报 mm: fix build error in fix_to_virt 错误的问题)
--- raw/linux-4.15.2/arch/arm/mm/mmu.c	2018-02-07 11:14:15.000000000 -0800
+++ linux-4.15.2//arch/arm/mm/mmu.c	2022-09-15 02:11:45.407671905 -0700
@@ -1599,7 +1599,7 @@
 		pte_t *pte;
 		struct map_desc map;
 
-		map.virtual = fix_to_virt(i);
+		map.virtual = __fix_to_virt(i);
 		pte = pte_offset_early_fixmap(pmd_off_k(map.virtual), map.virtual);
 
 		/* Only i/o device mappings are supported ATM */
  • 设置/lib/Kconfig.debug
--- raw/linux-4.15.2/lib/Kconfig.debug	2018-02-07 11:14:15.000000000 -0800
+++ linux-4.15.2/lib/Kconfig.debug	2022-09-15 02:06:38.596717691 -0700
@@ -198,6 +198,32 @@
 	  instance. See Documentation/dev-tools/gdb-kernel-debugging.rst
 	  for further details.
 
+config NO_AUTO_INLINE
+	bool "Disable compiler auto-inline optimizations"
+	help
+	  This will prevent the compiler from optimizing the kernel by
+	  auto-inlining functions not marked with the inline keyword.
+	  With this option, only functions explicitly marked with
+	  "inline" will be inlined. This will allow the function tracer
+	  to trace more functions because it only traces functions that
+	  the compiler has not inlined.
+
+	  Enabling this function can help debugging a kernel if using
+	  the function tracer. But it can also change how the kernel
+	  works, because inlining functions may change the timing,
+	  which could make it difficult while debugging race conditions.
+
+	  If unsure, select N.
+
+config ENABLE_WARN_DEPRECATED
+	bool "Enable __deprecated logic"
+	default y
+	help
+	  Enable the __deprecated logic in the kernel build.
+	  Disable this to suppress the "warning: 'foo' is deprecated
+	  (declared at kernel/power/somefile.c:1234)" messages.
+
+
 config ENABLE_WARN_DEPRECATED
 	bool "Enable __deprecated logic"
 	default y
  • 然后就是make menuconfig 的设置
    选择

Compiler optimization level

  (X) Optimize for better debugging experience (-Og) 

参考资料

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐