by quickmouse(quickmouse@263.net)
最近项目当中的LKM(Linux Kernel Module)部分需要支持多CPU的机器,也就是SMP系统。Reid说要支持SMP需要把代码check out到SMP的机器上编译一道,否则不行,他自己试过在Makefile当中加入-D__SMP__或者-DCONFIG_SMP,在单CPU机器上编译出来的代码还是不能在SMP上跑。
那不是意味着项目代码无法在一台机器上完成?我是一个懒人,所以决定查一下到底怎么回事。发信给scz,问他是不是可以在单CPU机器上编译出支持SMP的LKM,这个土人说应该是可以的,但是怎么弄忘记了。真是枉费我叫他四哥呀,哼哼。于是把笔记本抱到SMP平台旁边决心搞定这个问题(kernel panic也方便reboot嘛)。
虽然scz没能给出具体的建议,但是既然他说可以,那总比我忙活半天结论是不行的强,于是沿着代码找问题。先试图直接在Makefile当中加-DCONFIG_SMP,结果发现这个define在还没有过完头文件的部分就被“过滤”掉了。怎么回事?
原来redhat内核源码涉及LKM的部分首先包含了autoconf.h头文件,在那里,-DCONFIG_SMP被undefine掉了。追查原因是因为定义了__module__up或者__module__BOOT。进一步追查这两个定义,发现是在rhconfig.h里面完成的。回到源码上增加对这两个define的判断,发现是否在Makefile当中增加-DCONFIG_SMP,__module__BOOT都没有出现,而__module__up是有的,也就导致了-DCONFIG_SMP失效。回到rhconfig.h当中检查发现有__module__up和__module__smp的互斥关系,醒悟up就是uni-process,单CPU,再看rhconfig.h前包含了/boot/kernel.h头文件,当中定义__BOOT_KERNEL_UP 1,而__BOOT_KERNEL_SMP 0,于是决定在Makefile当中定义__BOOT_KERNEL_SMP=1,再编译,成功在源码当中检测到CONFIG_SMP。测试LKM成功。
结论:
Redhat的源码判断比较变态,相互关系较复杂。当然,这对于编译内核来说可能提高了可维护性,但是如果只是借用内核头文件来编译LKM来说,不注意这个关系,就会得到无法在单CPU环境下编译出SMP的LKM的结论
Trackback: http://tb.donews.net/TrackBack.aspx?PostId=488216