Debian编译3.4内核总结

2012年09月12日 分类:DebianLinux

Debian6.0的稳定版用了很久了,感觉是不错,唯一的不足之处就是发热量好像大了点,看个视频风扇就很给力了。听说3.2以后的内核在电源管理方面做了优化,于是想试试新的内核,3.6还在开发阶段,3.4自然是不二之选了。
首先上一张效果图。 kernel-3.4 接下来就开始了。

1.安装工具

我现在是要用debian的方式来编译内核,所以要安装debian编译工具kernel-package,常用编译包fakeroot,build-essential

aptitude install kernel-package fakeroot build-essential

2.下载源码

去kernel官网下载源码,地址:http://www.kernel.org/pub/linux/kernel/v3.x/ 里面有所有的3.0以上的内核源码,你也可以选其他版本的,3.2的其实也不错。下载好后解压:

tar xvjf linux-3.4.10.tar.bz2

3.配置内核

进入解压出来的目录,make menuconfig,根据自己的电脑配置内核。如果只要电脑能用就行的话,可以make defconfig来生成默认配置,也可以复制原来内核的配置到当前目录下,比如我的就是

cp /boot/config-2.6.32-5-686-bigmem ./.config

这样编译出来的内核是通用的,里面包括了很多驱动和modules,如果想定制内核的话可以在他上面修改,把不要的驱动去掉就行了。这里我要说几个注意事项:

  1. Enable the block layer下的Support for large (2TB+) block devices and files如果你的硬盘是sata的话一定要选上,不然在启动的时候会出现kernel panic的错误,亲身体会啊。
  2. Maximum number of CPUs这里的cpu数是算上虚拟出来的,比如我的i5cpu是双核的,但在超线程技术的支持下,每个cpu会有两个线程,这也是在上面那张图看到4个cpu的原因,所以这里我要选4。
  3. Virtualization是linux的虚拟化技术,也就是在linux中虚拟另一个linux客户机,一般人用不到的。如果选上会出现Make:*** Documentation/lguest: No such file or directory.Stop.的错误,如果真的需要这项技术,那就只能找技术手册了,我也不知道怎么弄。
其他的话网上都有很多配置详解的,选自己需要的,设备驱动的话可以用lspci来查看自己的设备,然后选相应的选项。

4.编译内核

配置好后记得保存,然后就可以编译了,运行

fakeroot make-kpkg --initrd kernel_image kernel_headers

fakeroot主要用于deb的打包,也可以直接用su以root来执行fakeroot后面的语句,效果是一样的。大概需要半个小时,看你的机器了。编译完后可以运行make-kpkg clean来清理编译过程中的中间文件,释放硬盘空间。

5.安装内核

编译完之后会在当前目录的上一层生成image和header,网上很多都说要先装image,我觉得没什么关系,直接

dpkg -i linux-*deb

他会自动修改grub.cfg,接着重启进入新内核,不出意外的话就能进入系统了。

6.安装驱动

新的内核会自带驱动,但我显卡支持的不是很好,拖动起来有重影,看来需要装官方驱动了。具体做法可以参照我另一篇文章Debian安装总结
但是这样装会出错,提示:

>/lib/modules/fglrx/build_mod/2.6.x/firegl_public.c:4159: error: ‘cpu_possible_map’ undeclared (first use in this function)  
/lib/modules/fglrx/build_mod/2.6.x/firegl_public.c:4159: error: (Each undeclared identifier is reported only once  
/lib/modules/fglrx/build_mod/2.6.x/firegl_public.c:4159: error: for each function it appears in.)  
/lib/modules/fglrx/build_mod/2.6.x/firegl_public.c:4159: warning: left-hand operand of comma expression has no effect  
/lib/modules/fglrx/build_mod/2.6.x/firegl_public.c: In function ‘KCL_fpu_begin’:  
/lib/modules/fglrx/build_mod/2.6.x/firegl_public.c:5833: error: implicit declaration of function ‘__save_init_fpu’  
make[2]: *** [/lib/modules/fglrx/build_mod/2.6.x/firegl_public.o] Error 1  
make[1]: *** [_module_/lib/modules/fglrx/build_mod/2.6.x] Error 2  
make[1]: Leaving directory `/home/fang/linux/linux-3.4.10'  
make: *** [kmod_build] Error 2  
build failed with return value 2

后来我找到了另一种安装方法,具体看这篇文章http://forum.ubuntu.org.cn/viewtopic.php?f=42&t=379588
我这里也记录一下:
下载官方12.6驱动,保存到home目录。执行

./amd-driver-installer-12-6-x86.x86_64.run --extract amd.8.98

解压安装包,然后打开amd.8.98/common/lib/modules/fglrx/build_mod,修改firegl_public.c和kcl_ioctl.c文件。(可以先从后面开始修改,这样行号就可以对应起来了)
修改firegl_public.c

把原来34行附近 
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33)
#include <generated/autoconf.h>
#else
#include <linux/autoconf.h>
#endif

#if !defined(CONFIG_X86) 
#if !defined(CONFIG_X86_PC) 

修改成
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33)
#include <generated/autoconf.h>
#else
#include <linux/autoconf.h>
#endif

#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
#define cpu_possible_map (*(cpumask_t *)cpu_possible_mask)
#define cpu_online_map (*(cpumask_t *)cpu_online_mask)
#endif

#if !defined(CONFIG_X86) 
#if !defined(CONFIG_X86_PC) 

184行附近 
#include <linux/kmod.h>
#include <linux/sysrq.h>
#include <linux/string.h>
#include <linux/gfp.h>
#include <linux/swap.h>
#include "asm/i387.h"

#include "firegl_public.h"
#include "kcl_osconfig.h"

修改成
#include <linux/kmod.h>
#include <linux/sysrq.h>
#include <linux/string.h>
#include <linux/gfp.h>
#include <linux/swap.h>
#include "asm/i387.h"
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
#include <asm/fpu-internal.h>
#endif

#include "firegl_public.h"
#include "kcl_osconfig.h"


把原来4168行附近
static int kasInitExecutionLevels(unsigned long level_init)
{
unsigned int p;
KCL_DEBUG5(FN_FIREGL_KAS, "%d\n", level_init);
for_each_cpu_mask(p, cpu_possible_map)
{
KCL_DEBUG1(FN_FIREGL_KAS,"Setting initial execution level for CPU # %d\n", p);
preempt_disable();
per_cpu(kasExecutionLevel, p) = level_init;
preempt_enable();
}

修改成
static int kasInitExecutionLevels(unsigned long level_init)
{
unsigned int p;
KCL_DEBUG5(FN_FIREGL_KAS, "%d\n", level_init);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
for_each_possible_cpu(p)
#else
for_each_cpu_mask(p, cpu_possible_map)
#endif
{
KCL_DEBUG1(FN_FIREGL_KAS,"Setting initial execution level for CPU # %d\n", p);
preempt_disable();
per_cpu(kasExecutionLevel, p) = level_init;
preempt_enable();
}

把原5825行

struct task_struct *cur_task = current;
preempt_disable();
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)
/* The thread structure is changed with the commit below for kernel 3.3:

修改成 

struct task_struct *cur_task = current;
preempt_disable();
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
/* The thread structure is changed with the commit below for kernel 3.3:

也就是3,3,0改成3,4,0。

再修改kcl_ioctl.c

把原来217行附近
* \param size [in] Number of bytes to allocate
* \return Pointer to allocated memory
*/
void* ATI_API_CALL KCL_IOCTL_AllocUserSpace32(long size)
{
void __user *ret = COMPAT_ALLOC_USER_SPACE(size);

修改成
* \param size [in] Number of bytes to allocate
* \return Pointer to allocated memory
*/
#ifndef CONFIG_X86_X32
DEFINE_PER_CPU(unsigned long, old_rsp);
#endif
void* ATI_API_CALL KCL_IOCTL_AllocUserSpace32(long size)
{
void __user *ret = COMPAT_ALLOC_USER_SPACE(size);

然后在amd.8.98文件夹里执行

./ati-installer.sh 8.98 --buildpkg Debian/stable

建立deb安装包。再安装就行了。 也可以直接就安装了,以root身份:

./ati-installer.sh 8.98 --install

再aticonfig –initial -f初始化下驱动,重启就行了。

作者:wuyuan 本文来自Wuyuan's Blog 转载请注明,谢谢! 文章地址: https://wuyuans.com/2012/09/debian-complie-3-4-kernel