热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用容器编译Linux内核并启动运行

本文目标是构建随处可用的内核开发环境,用于Linux内核调度器的研究。开发环境的开发套件由docker,ubuntu14.04,qemu,vim,zsh等构成。按照该开发环境的套件

本文目标是构建随处可用的内核开发环境,用于Linux内核调度器的研究。开发环境的开发套件由docker,ubuntu14.04,qemu,vim,zsh等构成。

按照该开发环境的套件要求,将在docker中构建ubuntu14.04系统,并构建内核编译和源码查看环境。主要步骤如下:

  1. 基于Docker安装Ubuntu-14.04
  2. 登录Docker中的Ubuntu-14.04
  3. 在ubuntu中安装qemu,vim,zsh
  4. 下载Linux内核源码,并编译
  5. 创建磁盘,启动编译后的内核

1. 基于Docker安装Ubuntu-14.04。指令如下所示:

axel -n 10 https://download.openvz.org/template/precreated/ubuntu-14.04-x86_64.tar.gz

cat ubuntu-14.04-x86_64.tar.gz | docker import - ubuntu:14.04

docker images

2. 登录Docker中的ubuntu-14.04

docker run -p 301:22 -d --name test ubuntu /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf

ssh [email protected] -p 301

3. 在ubuntu中安装qemu,vim,zsh

sudo apt-get install qemu vim zsh axel wget curl

4. 下载Linux内核源码,并编译

axel -n 10 https://mirrors.edge.kernel.org/pub/linux/kernel/v4.x/linux-4.18.tar.gz

tar -zxfv linux-4.18.tar.gz

cd linux-4.18

关于Linux内核编译,可以参考博客。具体过程如下:

make help  # 查看make参数

make x86_64_defconfig

结果发现,缺乏编译器,此外,在编译过程中,还发现缺乏依赖库。因此,一次安装如下依赖库

sudo apt-get install bison flex qemu bc build-essential gcc g++ libelf-dev libssl-dev

make x86_64_defconfig

make bzImage  # 编译内核

make modules # 编译模块

编译完成之后,将生成内核压缩文件arch/x86/boot/bzImage

5. 创建磁盘,启动编译后的内核

起初,打算直接在docker中用qemu启动bzImage,然而,出现了图形化界面使用错误的情况。

root# qemu-system-x86_64 -m 512M -smp 4 -kernel ./bzImage
Could not initialize SDL(No available video device) - exiting

鉴于这样的情况,有两种方案:

(1)在qemu启动时使用-curses参数,可直接启动(亲测有效)

(2)将容器中编译好的压缩内核bzImage复制(docker cp)到本地host系统中,基于qemu启动。

基于第二种方案构建的开发环境,缺少了docker一贯的隔离性,即要求host系统中安装qemu环境,且主机系统和虚拟机系统的内容来回传递。因此,直接使用第一种方案,但是需要另外连接的终端终止当前qemu程序才能重新回到容器的shell中。

在启动编译后的压缩内核时,出现无法找到文件系统的错误:

使用容器编译Linux内核并启动运行

为此,需要创建磁盘镜像,制作根文件系统,且准备init程序才能启动编译后的内核。

但是在创建磁盘并挂在的过程中,出现无法找到loop设备的错误。

qemu-img create -f raw disk.raw 512M

mkfs -t ext4 ./disk.raw   # 若没有mkfs.ext4,则安装e2fsprogs套件,sudo apt-get install e2fsprogs

sudo mount -o loop ./disk.raw ./img

mount: Could not find any loop device. Maybe this kernel does not know
       about the loop device? (If so, recompile or `modprobe loop'.)

最快捷方便的解决方案就是在docker run时,加入特权:

docker run --privileged=true ...

目前,可以挂在文件系统,但是缺乏启动程序init,因此基于busybox构建启动程序。但是在编译过程中,出现缺少curses.h头文件的情况,这是因为缺少套件ncurses devel。

make defconfig

make menuconfig

In file included from scripts/kconfig/lxdialog/checklist.c:24:0:
scripts/kconfig/lxdialog/dialog.h:31:20: fatal error: curses.h: No such file or directory
 #include CURSES_LOC
                    ^
compilation terminated.
make[2]: *** [scripts/kconfig/lxdialog/checklist.o] Error 1
make[1]: *** [menuconfig] Error 2
make: *** [menuconfig] Error 2

sudo apt-get install libncurses5-dev # 缺少ncurses devel套件

然后,再次编译时,将busybox编译为静态的二进制文件。然后make编译,并安装到挂在的img目录中。

Busybox Settings --->

              --- Build Options

               [*] Build BusyBox as a static binary (no shared libs)

# make 

# make CONFIG_PREFIX= install

# ls   #可以看到包含了更多目录

使用容器编译Linux内核并启动运行

此外,还需要创建额外的文件,包括rcS,inittab,proc,sys,dev等,具体可以参考博客。

以下是直接可用的脚本,需要修改相应的路径。

#!/bin/sh

# note: Linux kernel and busybox are in the same directory
path_to_Linux_kernel=linux-4.18
path_to_busybox=busybox-1.30.0
path_to_root=`pwd`

cd $path_to_Linux_kernel
#make clean
#make distclean
#make x86_64_defconfig
#make bzImage
#make modules

# obtain the bzImage
cp arch/x86/boot/bzImage $path_to_root

# create disk by type ext4
cd $path_to_root
if [ -d img ]; then
    umount img
    rm -rf img
fi

if [ -e disk.raw ]; then
    rm disk.raw
fi

qemu-img create -f raw disk.raw 512M
mkfs -t ext4 disk.raw

mkdir img
sudo mount -o loop disk.raw img  # note that, docker run --privileged=true

# install modules and init program
cd $path_to_Linux_kernel
sudo make modules_install INSTALL_MOD_PATH=../img

cd $path_to_root/$path_to_busybox
if [ -e busybox ]; then
    make CONFIG_PREFIX=../img install
else
    echo "Busybox is not built yet. Please build the busybox first!"
    exit 2
fi

# update the init program
cd $path_to_root/img

mkdir -p etc/init.d
mkdir proc
mkdir sys
mkdir dev

touch etc/init.d/rcS
echo "#/bin/sh" > etc/init.d/rcS
echo "mount -t proc proc /proc" >> etc/init.d/rcS
echo "mount -t sysfs sysfs /sys" >> etc/init.d/rcS
chmod +777 etc/init.d/rcS

# start the bzImage
cd $path_to_root
qemu-system-x86_64 -curses -m 512M -smp 4 -kernel bzImage -drive format=raw,file=disk.raw -append "init=/linuxrc root=/dev/sda"

最后,在docker容器中的ubuntu就可以启动qemu了。

qemu-system-x86_64 -curses -m 512M -smp 2 -kernel bzImage -drive format=raw,file=disk.raw -append "init=/linuxrc root=/dev/sda"

终结

在所有的环境搭建好之后,要保存(commit)当前容器的状态,并推送到远程网络(push),这样就可以在任何一台装有docker的系统中,使用该环境,进行Linux内核开发和学习。

docker commit -m "update with busybox" [:]

 


推荐阅读
  • 在Kubernetes上部署JupyterHub的步骤和实验依赖
    本文介绍了在Kubernetes上部署JupyterHub的步骤和实验所需的依赖,包括安装Docker和K8s,使用kubeadm进行安装,以及更新下载的镜像等。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
  • 现在比较流行使用静态网站生成器来搭建网站,博客产品着陆页微信转发页面等。但每次都需要对服务器进行配置,也是一个重复但繁琐的工作。使用DockerWeb,只需5分钟就能搭建一个基于D ... [详细]
  • 本文介绍了在mac环境下使用nginx配置nodejs代理服务器的步骤,包括安装nginx、创建目录和文件、配置代理的域名和日志记录等。 ... [详细]
  • web.py开发web 第八章 Formalchemy 服务端验证方法
    本文介绍了在web.py开发中使用Formalchemy进行服务端表单数据验证的方法。以User表单为例,详细说明了对各字段的验证要求,包括必填、长度限制、唯一性等。同时介绍了如何自定义验证方法来实现验证唯一性和两个密码是否相等的功能。该文提供了相关代码示例。 ... [详细]
  • 如何查询zone下的表的信息
    本文介绍了如何通过TcaplusDB知识库查询zone下的表的信息。包括请求地址、GET请求参数说明、返回参数说明等内容。通过curl方法发起请求,并提供了请求示例。 ... [详细]
  • 本文介绍了在Mac上安装Xamarin并使用Windows上的VS开发iOS app的方法,包括所需的安装环境和软件,以及使用Xamarin.iOS进行开发的步骤。通过这种方法,即使没有Mac或者安装苹果系统,程序员们也能轻松开发iOS app。 ... [详细]
  • 篇首语:本文由编程笔记#小编为大家整理,主要介绍了软件测试知识点之数据库压力测试方法小结相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了5个基本Linux命令行工具的现代化替代品,包括du、top和ncdu。这些替代品在功能上进行了改进,提高了可用性,并且适用于现代化系统。其中,ncdu是du的替代品,它提供了与du类似的结果,但在一个基于curses的交互式界面中,重点关注占用磁盘空间较多的目录。 ... [详细]
  • 本文介绍了解决java开源项目apache commons email简单使用报错的方法,包括使用正确的JAR包和正确的代码配置,以及相关参数的设置。详细介绍了如何使用apache commons email发送邮件。 ... [详细]
  • 大坑|左上角_pycharm连接服务器同步写代码(图文详细过程)
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了pycharm连接服务器同步写代码(图文详细过程)相关的知识,希望对你有一定的参考价值。pycharm连接服务 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了markdown[软件代理设置]相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 有意向可以发简历到邮箱内推.简历直达组内Leader.能做同事的话,内推奖励全给你. ... [详细]
  • PreparedStatement防止SQL注入
    添加数据:packagecom.hyc.study03;importcom.hyc.study02.utils.JDBCUtils;importjava.sql ... [详细]
author-avatar
昱辰190974945122
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有