为Guest Ubuntu编译内核

在上一篇 Vagrant 安装Guest Ubuntu 中介绍了利用vagrant 快速部署Guest Ubuntu,下一步我们需要安装一个自己编译的内核,作为后续的学习环境。
我们可以在Host Ubuntu中编译内核,也可以在Guest Ubuntu中编译,推荐在Host Ubuntu中编译,这样编译速度更快,但是即便在Host中编译,将来我们还是需要在Guest Ubuntu中编译Vbox Guest Addition driver. 所以在Host和Guest Ubuntu中安装如下软件:

# 在Host Ubuntu中安装
root@ubuntu:~/vagrant# sudo apt install bison flex libelf-dev libncurses5-dev \
    openssl libssl-dev gcc bc make dpkg-dev git socat gdb libbabeltrace-dev
# 到Guest Ubuntu中安装
root@ubuntu:~/vagrant# vagrant up
root@ubuntu:~/vagrant# vagrant ssh
vagrant@ubuntu-xenial:~$ sudo apt install bison flex libelf-dev libncurses5-dev \
    openssl libssl-dev gcc bc make dpkg-dev git socat gdb libbabeltrace-dev
vagrant@ubuntu-xenial:~$ exit

现在建议创建另外一个snapshot.

root@ubuntu:~/vagrant# vagrant halt
root@ubuntu:~/vagrant# vagrant snapshot save installed-toolchains
root@ubuntu:~/vagrant# vagrant snapshot list
fresh-installed-ubuntu
installed-toolchains

前面说过,Guest OS中 /vagrant目录和Host OS的$HOME/vagrant目录是共享的,所以只要把内核源代码下载到Host OS就可以了。将来的试验过程中我们会对内核进行修改,所以用git建立一个新的branch,方便记录我们的修改。

root@ubuntu:~/vagrant# git clone https://github.com/torvalds/linux.git
root@ubuntu:~/vagrant# cd linux 

# create a testing branch and check out this branch
root@ubuntu:~/vagrant/linux # git branch testing
root@ubuntu:~/vagrant/linux # git checkout testing

然后就可以编译内核了,通常编译的步骤是make menuconfig,但是自己难免会漏选,所以我们 拷贝Guest Ubuntu内核的config 文件到共享目录:

# This command in Guest Ubuntu
vagrant@ubuntu-xenial:~$ cp /boot/config-`uname -r` /vagrant/config

# following command in Host Ubuntu
root@ubuntu:~# cd vagrant/linux
root@ubuntu:~/vagrant/linux# mkdir -pv ../obj/x86_64
root@ubuntu:~/vagrant/linux# cp ../config ../obj/x86_64
root@ubuntu:~/vagrant/linux# yes '' | make O=../obj/x86_64/ oldconfig

现在内核已经配置好了,但是我们还要enable 一些debug的配置,为后续学习做准备。同样,如果通过make menuconfig手动配置,通常找到某一个选项,结果它还依赖其它的,我们可以让kernel的make file 自动处理,只需要做如下改动:

diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index f9bdd02..e12c6ac 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -132,6 +132,11 @@ PHONY += kvmconfig
 kvmconfig: kvm_guest.config
        @:

+PHONY += testingconfig
+testingconfig: testing.config
+       @:
+
+
 PHONY += xenconfig
 xenconfig: xen.config
        @:
diff --git a/kernel/configs/testing.config b/kernel/configs/testing.config
new file mode 100644
index 0000000..e81c872
--- /dev/null
+++ b/kernel/configs/testing.config
@@ -0,0 +1,8 @@
+CONFIG_FRAME_POINTER=y
+CONFIG_KGDB=y
+CONFIG_DEBUG_INFO=y
+CONFIG_KGDB_SERIAL_CONSOLE=y
+CONFIG_DEBUG_INFO_DWARF4=y
+CONFIG_FUNCTION_TRACER=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y

然后使用make testingconfig merge这些选项到.config文件。

root@ubuntu:~/vagrant/linux# make O=../obj/x86_64 testingconfig

现在就可以编译了,-j6是用6个线程编译,可以适当调整:

root@ubuntu:~/vagrant/linux# make O=../obj/x86_64 -j6 && \
    make O=../obj/x86_64 bindeb-pkg

现在就是漫长的等待了,记得把自己的改动提交到自己的git branch

root@ubuntu:~/vagrant/linux# git add kernel/configs/testing.config
root@ubuntu:~/vagrant/linux# git commit -a -m "add testing.config"

推荐使用Host Ubuntu编译,如果想尝试在Guest Ubuntu编译,需要注意的是:Guest OS中对共享目录的文件调用mmap时会失败,错误为:

 Could not mmap file: vmlinux
 make: *** [vmlinux] Error 1

因此需要把编译内核的脚本修改一下,此方法出自这里。原理就是把编译时的vmlinux文件拷贝到/tmp目录下,然后执行scripts/sortextable /tmp/vmlinux,最后再考回来。patch如下:

diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
index 9045823..dd5c6f7 100755
--- a/scripts/link-vmlinux.sh
+++ b/scripts/link-vmlinux.sh
@@ -155,7 +155,10 @@ mksysmap()

 sortextable()
 {
-       ${objtree}/scripts/sortextable ${1}
+       cp ${1} /tmp/.${1}
+       scripts/sortextable /tmp/.${1}
+       cp /tmp/.${1} ${1}
+#      ${objtree}/scripts/sortextable ${1}
 }

 # Delete output files in case of error

下一篇介绍在Vagrant中启动新编译的内核。

你可能感兴趣的:(为Guest Ubuntu编译内核)