要想编写驱动,建立内核目录树是必须的.也即是在PC Linux上编译内核,加入到PC Linux中,以这个内核作为PC Linux的内核启动.
1. 我的系统是Ubuntu 12.4,先查看一下原先的内核版本:
cody@cody-linux:/$ uname -a Linux cody-linux 3.2.0-29-generic-pae #46-Ubuntu SMP Fri Jul 27 17:25:43 UTC 2012 i686 i686 i386 GNU/Linux
原来是3.2.0-29,还挺新的,起码到目前为止是这样的
2. 安装必要的软件包:
cody@cody-linux:/$ sudo apt-get install build-essential kernel-package libncurses5-dev
3. 去https://www.kernel.org/pub/linux/kernel/选择一个合适的版本下载.因为我的开发板使用的内核是2.6.29.4,所以我选择"linux-2.6.29.4.tar.bz2”, 下载完成后放到一个合适的位置,我的是:/home/cody/kernel/,然后右键选择解压在这里(让命令去S吧,点击二下就可以做的事,我干嘛还要去命终端打一堆的命令来解压呢?)
4. 打开终端,进入到刚刚解压出来的目录:
cody@cody-linux:/$ cd ~/k*/l* cody@cody-linux:~/kernel/linux-2.6.29.4$
看到了吧,使用通配符*,快速进入到目标目录,因为在我的主目录下以k开关的只有kernel这个目录,而kernel目录下以l开关的也只有linux-2.6.29.4这个目录,如果还有一些目录是以l开头,可能进入的不是你想要的目录,多打几个前面的字母,直到能区别为止即可.
5. 先配置一下. 我使用的是默认的配置,因为我不懂行那么多配置到底代表什么意思.是否可行有待时间验证
sudo make-kpkg clean #如果之前已经make过,最好clean一下
sudo make menuconfig #会打开一下图形界面的配置,我直接Exit,问我是否保存,我选择Yes
sudo make-kpkg --initrd --append-to-version=-fordevkernel kernel-image kernel-headers
其中字符串”fordevkernel”可以换成你想要的.--append-to-version的解释是这样的(来源):
--append-to-version= you can write any string that helps you identify the kernel, but it must begin with a minus (-) and must not contain whitespace
6. 根据make要很久才能跑玩,可是我的跑了大概2分钟的时候,出现一个错误:
gcc: 错误: elf_i386:没有那个文件或目录 make[2]: *** [arch/x86/vdso/vdso32-int80.so.dbg] 错误 1 make[1]: *** [arch/x86/vdso] 错误 2 make: *** [sub-make] 错误 2
解决办法:
原因是 gcc 4.6 不再支持 linker-style 架构。讲 arch/x86/vdso/Makefile 中, 将以 VDSO_LDFLAGS_vdso.lds 开头所在行的 "-m elf_x86_64" 替换为 "-m64"。 将以 VDSO_LDFLAGS_vdso32.lds 开头所在行的 "-m elf_x86" 替换为 "-m32"。
7. 又跑了半小时左右,出现如下错误:
include/linux/kvm.h:241:9: 错误: 重复的成员‘padding’ arch/x86/kvm/svm.c: 在函数‘io_interception’中: arch/x86/kvm/svm.c:1099:30: 警告: 变量‘rep’被设定但未被使用 [-Wunused-but-set-variable] arch/x86/kvm/svm.c:1099:12: 警告: 变量‘down’被设定但未被使用 [-Wunused-but-set-variable] make[2]: *** [arch/x86/kvm/svm.o] 错误 1 make[1]: *** [arch/x86/kvm] 错误 2 make[1]:正在离开目录 `/home/cody/kernel/linux-2.6.29.4' make: *** [debian/stamp/build/kernel] 错误 2
百度,Google,Bing…. 没有找到直接使用的信息,有的说是配置错误.好吧,重新make menuconfig, 从出错信息来看,应该是kvm相关的.因为没有用到kvm,为何不干脆关掉这个选项呢?ok,就这样!
找到Virtualization选择,把勾选去掉.如下例如所示.
继续make, 还有一个错误,重复的定义'codec’,解决办法是找到 include/sound/soc-dai.h,可以看到里面定义了一个struct和一个union类型的codec, 我注释掉struct的那个,不知道这样做会不会有问题. 反正我的是编译过了.
6. 等了好久好久,终于编译过了, 内牛满面!! 生成的安装文件在上层目录中, 返回上层目录(~/kernel),可以看到生成了二个deb文件,一个linux-image-开头的内核文件和一个lnux-headers-开头的头文件.
7. 使用dpkg –i 安装上述二个文件.
8. 查看一下启动菜单文件里有没有进加入的内核的启动选项
vi /boot/grub/grub.cfg
9. 启动试试,哈哈,因为我在vmware里运行的,默认没有打开启动菜单显示的,所以重新启动之后看不到启动菜单,还是进入原来的内核系统
10. 修改/etc/default/grub文件中
GRUB_HIDDEN_TIMEOUT=1 GRUB_TIMEOUT=10 #10表示等待的时间,可以修改成你喜欢的时间
还有一些地方要修改,打开/etc/grub.d/30_os-prober,按如下修改(来源)
if [ "x\${timeout}" != "x-1" ]; then if keystatus; then if keystatus --shift; then set timeout=-1 else set timeout=10 # 修改这里 1/3 fi else if sleep$verbose --interruptible 3 ; then set timeout=10 # 修改这里 2/3 fi fi fi EOF else cat << EOF if [ "x\${timeout}" != "x-1" ]; then if sleep$verbose --interruptible ${GRUB_HIDDEN_TIMEOUT} ; then set timeout=10 # 修改这里 3/3 fi fi
修改之后不要忘了更新grub
sudo update-grub
11. 重新启动,这时应该可以选择内核了.
12. 选择新编译的内核启动之后, 会提示一些错误. 但还算可以用. 先这样吧.