昨天直接从git源上update到最新upstream内核版本,编译的内核却无法启动。一开始我以为是.config文件不对,于是试了各种方法,make localmodconfig,甚至make allmodconfig,居然还是起不来。于是在grub里加了个" vga=771 ",看看启动失败的具体报错信息,发现里面有句:

kernel tool old

神奇,这3.12的内核还老啊,在google上找了一下,还真有人遇到同样的报错,文章, 不过他是在arm上编译,gcc版本和内核版本差异很大,我这是rhel6,不应该有这么严重的问题,如果rhel6上都启动不了upstream内核,那应该很多人会发现的。
折腾了一圈,还是仔细看看失败的报错信息吧,这次才看到,除了“kernel too old”,居然还有

Not tained 2.6.19-rc79

莫名奇妙,明明是3.12内核,怎么说是2.6.19?这应该就是失败的原因了,于是沿着dump_stack()函数一路找回去,看到了这个

struct uts_namespace init_uts_ns = {
        .kref = {
                .refcount       = ATOMIC_INIT(2),
        },     
        .name = {
                .sysname        = UTS_SYSNAME,
                .nodename       = UTS_NODENAME,
                .release        = UTS_RELEASE,
                .version        = UTS_VERSION,
                .machine        = UTS_MACHINE,
                .domainname     = UTS_DOMAINNAME,
        },
        .user_ns = &init_user_ns,
        .proc_inum = PROC_UTS_INIT_INO,
};
EXPORT_SYMBOL_GPL(init_uts_ns);

原来打印的2.6.19-rc79是从UTS_RELEASE和UTS_VERSION宏来的,一找UTS_RELEASE在哪里定义的,发现居然有三个头文件,其中一个include/linux/version.h里是2.6.19,但是git一看,这个文件根本不在git库里,应该是某次我checkout到旧版本残留下来的......就是它干扰了启动过程。看来编译内核前,除了make clean以外,还要把不在git里的文件删掉,免得干扰正常编译。