zhangjun0718 发表于 2010-08-27 17:52

求助:如何用-O0优化级别编译Linux内核?(以前发过,无解,再唤醒一下大家)

我想调试内核源码,发现代码执行顺序与源码不太一致,根据经验,这应该是打开优化选项的结果,于是我想关闭优化编译Linux内核,也就是将内核的编译选项 -O2 改为 -O0,我直接修改了内核源码顶层目录下 Makefile 文件的 525 行:
ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
#CFLAGS    += -Os
CFLAGS      += -O0
else
#CFLAGS    += -O2
CFLAGS      += -O0
endif
其中注释掉到是原来的,注释下面是我改动的地方,也就是只是将-Os和-O2改成-O0而已。
我到目标板用的发行版是 montavista pro 4.0.1,host是 Fedora12,编译器是 arm_v5t_le-gcc。
修改了Makefile之后,重新编译内核出现很多错误,错误信息在后面。
错误信息中提到的那些未定义标号肯定是定义过的,因为用-O2或者-O1优化选项都能够顺利编译通过,那么仅仅修改了优化级别,为什么结果就不一样了呢?
希望高手解答啊 !!

以下是编译错误:
$ make ARCH=arm CROSS_COMPILE=arm_v5t_le- uImage
CHK    include/linux/version.h
SPLITinclude/linux/autoconf.h -> include/config/*
SYMLINK include/asm-arm/arch -> include/asm-arm/arch-davinci
make: `arch/arm/kernel/asm-offsets.s' is up to date.
make: `include/asm-arm/mach-types.h' is up to date.
CHK    include/linux/compile.h
UPD    include/linux/compile.h
CC      init/version.o
LD      init/built-in.o
CHK    usr/initramfs_list
GEN    .version
CHK    include/linux/compile.h
dnsdomainname: 未知的主机
UPD    include/linux/compile.h
CC      init/version.o
LD      init/built-in.o
LD      .tmp_vmlinux1
init/built-in.o(.init.text+0x1e8c): In function `identify_ramdisk_image':
init/do_mounts_rd.c:92: undefined reference to `ntohl'
arch/arm/mm/built-in.o(.text+0x1624): In function `adjust_pte':
arch/arm/mm/fault-armv.c:77: undefined reference to `cpu_tlb'
arch/arm/mm/built-in.o(.text+0x2360): In function `do_translation_fault':
arch/arm/mm/fault.c:363: undefined reference to `cpu_tlb'
arch/arm/mm/built-in.o(.text+0x3c44): In function `free_pgd_slow':
arch/arm/mm/mm-armv.c:249: undefined reference to `cpu_tlb'
arch/arm/mm/built-in.o(.text+0x3de4): In function `setup_mm_for_reboot':
arch/arm/mm/mm-armv.c:590: undefined reference to `cpu_tlb'
arch/arm/mm/built-in.o(.init.text+0x1414): In function `paging_init':
arch/arm/mm/init.c:519: undefined reference to `cpu_tlb'
arch/arm/mm/built-in.o(.init.text+0x2734):arch/arm/mm/mm-armv.c:559: more undefined references to `cpu_tlb' follow
fs/built-in.o(.text+0xf2460): In function `xdr_decode_fattr':
fs/nfs/nfs2xdr.c:125: undefined reference to `ntohl'
fs/built-in.o(.text+0xf2480)s/nfs/nfs2xdr.c:126: undefined reference to `ntohl'
fs/built-in.o(.text+0xf24a0)s/nfs/nfs2xdr.c:127: undefined reference to `ntohl'
fs/built-in.o(.text+0xf24c0)s/nfs/nfs2xdr.c:128: undefined reference to `ntohl'
fs/built-in.o(.text+0xf24e0)s/nfs/nfs2xdr.c:129: undefined reference to `ntohl'
fs/built-in.o(.text+0xf2500)s/nfs/nfs2xdr.c:130: more undefined references to `ntohl' follow
fs/built-in.o(.text+0xf2958): In function `nfs_xdr_sattrargs':
fs/nfs/nfs2xdr.c:155: undefined reference to `htonl'
fs/built-in.o(.text+0xf29ac):fs/nfs/nfs2xdr.c:156: undefined reference to `htonl'
fs/built-in.o(.text+0xf2a00):fs/nfs/nfs2xdr.c:157: undefined reference to `htonl'
fs/built-in.o(.text+0xf2a54):fs/nfs/nfs2xdr.c:158: undefined reference to `htonl'
fs/built-in.o(.text+0xf2aa8):fs/nfs/nfs2xdr.c9: undefined reference to `htonl'
fs/built-in.o(.text+0xf2b04):fs/nfs/nfs2xdr.c:91: more undefined references to `htonl' follow
……

jzhang918 发表于 2010-08-27 23:52

回复 1# zhangjun0718


    我几年前做过。需要改一些linux kernel的code。linux kernel的代码有些地方需要enable优化才能编译,不改是不行的。还有一些地方实在很难改,但是对你调试影响不大,你可以单独对那些文件用优化编译。

EricFisher 发表于 2010-08-28 14:22

据茶水说,他要提个patch,来解决这个问题,呵呵

zhangjun0718 发表于 2010-08-28 15:54

呵呵,能不能先把这个path给我打上呀?zhangjun0718@163.com

Guang-Yuan.Wang 发表于 2010-08-30 22:42

-O0 主要是inline的问题,有些kernel代码是采用inline在compile时生成最终代码。
-O0关闭inline导致一些function没有优化掉,造成makefile和实际代码不匹配,所以有一些 undefined reference 出现

只要手工inline对应的代码就能在-O0下编译过kernel

EricFisher 发表于 2010-08-31 11:23

这样说来,或许你可以试试,在-O0的基础上,打开inline优化,查了下-O3会有下列inline优化。没试过是否可行。

          -finline-small-functions
          -findirect-inlining
          -fpartial-inlining
          -finline-functions
          -finline-functions-called-once

Guang-Yuan.Wang 发表于 2010-08-31 22:33

本帖最后由 Guang-Yuan.Wang 于 2010-08-31 22:34 编辑

回复 6# EricFisher

单纯的inline可能不行,内核一般是inline+ 相关优化配合,inline是基础,比如

inline int xx()
{
#ifdef CONFIG_TARGET_MIPS
return 1;
#else
return 0;
}

void yy()
{
if (xx())
    A();
else
    B();
}

假设A() 在mips相关代码实现,用户没有config mips target, -O2 (inline + 死代码消除) 所产生的代码不会 call A。

而 -O0 或者 单纯inline不死代码消除,都会产生 call A 的代码,而用户没有config mips target,所以不会编译链接 mips 相关代码,最后导致 B function undefined reference.

EricFisher 发表于 2010-09-01 09:28

哦,有意思。

gtkmm 发表于 2010-10-09 23:31

zen-source,make menuconfig里,有一个选项的。。。

lllaaa 发表于 2010-10-11 08:04

http://blog.chinaunix.net/u/355/showart_361635.html 不知道现在的linux版本还可不可以
页: [1]
查看完整版本: 求助:如何用-O0优化级别编译Linux内核?(以前发过,无解,再唤醒一下大家)