交叉编译busybox和Linux kernel 并在qemu上运行

转载请注明出处

原文地址: https://www.jianshu.com/p/5aaea4d41aa6

@简书

@earth_xmx

翻译部分

原文地址https://jasonblog.github.io/note/arm_emulation/compiling_linux_kernel_for_qemu_arm_emulator.html

上一次,我编译了无操作系统的ARM程序(bare-metal ARM programs)和U-boot. 本节,我们将在ARM平台上编译一个 linux kernel. 由于我没有真实的ARM设备, 所以本节我用QEMU模拟ARM设备。

linux内核代码和QEMU都支持VersatilePB平台。所以,我选择VersatilePB作为测试平台。交叉编译工具链,我选择 CodeSourcery ARM EABI toolchain.

内核代码可以从 http://kernel.org 上下载. 我选择最新的版本(version 2.6.33)并且解压缩到想关的目录。

在内核根代码中执行:

make ARCH=arm versatile_defconfig

上面的命令,使用了预定义的配置(arch/arm/configs/versatile_defconfig)。 这个配置让内核在VersatilePB板子上正常运行。执行上面的命令后,会把versatilepb的默认配置写入到根目录下的 .config 文件中。另外,执行如下命令在.config 的基础上进行微调配置。

make ARCH=arm menuconfig

我移除了模块支持,并且打开了EABI支持(同时支持 old ABI)。对于使用 CodeSourcery 交叉编译工具编译出的程序,其要想正常运行。这个选项必须要打开。

执行如下命令,进行编译。

make ARCH=arm CROSS_COMPILE=arm-none-eabi- all

如果使用GNU/Linux 工具链,应该执行如下进行编译:

make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- all

上面便于命令结束且没有报错的时候,会在 arch/arm/boot 下生成了一个 叫 zImage的文件。这个文件可以被 QEMU使用。

qemu-system-arm -M versatilepb -m 128M -kernel zImage

上面的命令:QEMU将执行zImage。内核会显示很多的启动信息。最后会显示它找不到文件系统。所以,我们下一步创建一个简单的文件系统。此文件系统仅包含一个"Hello world"可执行程序。

#include <stdio.h>

void main() {
  printf("Hello World!\n");
  while(1);
}

注意:程序最后要使用无限循环保证程序不退出。因为 linux 内核执行的第一个程序后,内核期望地一个程序永远都不结束,不然会包 kernel panic错误。

arm-none-linux-gnueabi-gcc -static    test.c   -o test

上面的命令会创建一个静态链接的二进制程序(静态代表其依赖的所有库都链接到一个单一的可执行程序里面了)。下面就可以创建文件系统了。

echo test | cpio -o --format=newc > rootfs

cpio 工具会从标准输入中读取一系列文件列表,并且会在标准输出中输出一个格式为newc的归档文件。我们这里把标准输出重定向到一个名为 rootfs的文件中。newc文件系统格式,是linux内核能够直接识别的文件系统。(而ext4这样的文件系统,需要内核加载相应的模块才能识别。)rootfs文件是一个文件系统的镜像文件,其中只包含一个文件(test可执行文件)。 QEMU可以把 rootfs文件传给内核(传入机制以后再说)。通过下面的命令启动内核。

qemu-system-arm -M versatilepb -m 128M -kernel zImage -initrd rootfs -append
"root=/dev/ram rdinit=/test"
#include <stdio.h>

void main() {
  printf("Hello World!\n");
  while(1);
}

实践部分

下面的实践在 ubuntu 22.04 中进行。上面原文的作者大概是在2010年左右整理出来的教程。现在都2022年了。希望可以按照他的教程,完成内核的编译与运行。

先下载 linux 内核源码,我这里选择的是2.6.34.1 跟原文有点小差别。

wget https://mirrors.edge.kernel.org/pub/linux/kernel/v2.6/linux-2.6.34.1.tar.bz2
tar xf linux-2.6.34.1.tar.bz2

如果下载失败,可以打开上面的网址,找一个差不多的内核应该也行。
部分
下载安装交叉编译工具链并配置(参考文章:https://developer.ridgerun.com/wiki/index.php/Code_Sourcery_ARM_toolchain_2011.09

wget https://sourcery.mentor.com/public/gnu_toolchain/arm-none-linux-gnueabi/arm-2011.09-70-arm-none-linux-gnueabi.bin
chmod +x arm-2011.09-70-arm-none-linux-gnueabi.bin
## 安装依赖:
sudo apt install lib32z1  ## 32位lib,如果是ubuntu其他版本,可能是安装其他包,请自行搜索解决。

## 执行安装程序(如果执行失败,请查看终端输出的错误log,然后解决)
./arm-2011.09-70-arm-none-linux-gnueabi.bin
## 一路按照提示,安装完成。

安装完后配置环境变量:(我的安装目录为~/CodeSourcery/)

export PATH=$PATH:~/CodeSourcery/Sourcery_CodeBench_Lite_for_ARM_GNU_Linux/bin
list.png

编译内核

编译内核之前,先安装依赖

sudo apt install make
sudo apt install gcc
sudo apt install libncurses5-dev 

编译内核: step1: 先使用versatile的默认配置去写入.config文件

cd linux-2.6.39.2/
make ARCH=arm versatile_defconfig

step2: 使用menuconfig 调整.config文件使内核支持 EABI

make ARCH=arm menuconfig

移除模块支持

menu1.png

在 Kernel Features 中打开 EABI支持

menu2.png

step3: 编译

make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- all

编译的时候会报一个错误:

err1.png

这里的解决办法是 kernel/timeconst.pl 的373 行做如下修改

correct1.png

然后重新执行上面的编译命令。编译成功后会在 源码目录下 arch/arm/boot/下面生成一个叫做 zImage的文件。这个就是内核文件了。

下面使用qemu启动内核了。

安装 qemu

sudo apt install qemu-system-arm 

启动内核

qemu-system-arm -M versatilepb -m 128M -kernel zImage

应看到如下启动信息

qemu-no-rootfs.png

可以看到最后有一行打印了 not syncing: VFS: unable to mount root fs on unkown ....

下面创建内核要启动的第一个进程 init

#include <stdio.h>

void main() {
  int num = 1;
  for (num = 1; num <= 10; ++num)
    printf("Hello World![num=%d]\n", num);
    
  while(1);
}

编译并制作rootfs

arm-none-linux-gnueabi-gcc -static init.c -o init
echo init | cpio -Hnewc -o > rootfs.img

重新启动内核

qemu-system-arm -M versatilepb -m 128M -kernel arch/arm/boot/zImage  -initrd ../test/rootfs.img -append "rdinit=/init"

可以看到如下

qemu-init.png

至此,我们已经完成了上面的教程。下面额外添加编译busybox到rootfs中去。

busybox编译到initrd中

下载busybox 源码

https://www.busybox.net/downloads/busybox-1.20.0.tar.bz2
tar xf busybox-1.20.0.tar.bz2

编译busybox源码

cd busybox-1.20.0
make ARCH=arm defconfig ## 使用默认配置
make ARCH=arm menuconfig ## 打开静态编译选项,把busybox编译成static形势,如同上面的init程序。
### Busybox Settings -> Build Options -> Build BusyBox as a static binary (no shared libs) 
## 不打开的话一会还要拷贝动态链接库到rootfs中,就比较麻烦。
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- install #编译源码

上述编译如果没有错误的话,会在 busybox源码目录下生成一个 _install 的目录。

制作 rootfs

cd _install
find . | cpio -Hnewc -o | gzip -9 > ../rootfs.img.gz
## rootfs.img.gz 文件保存在 busybox-1.20.0 下面了。

使用qemu加载启动

qemu-system-arm -M versatilepb -m 128M -kernel arch/arm/boot/zImage  -initrd ../busybox-1.20.0/rootfs.img.gz -append "rdinit=/bin/sh"

将会看到如下:

qemu-busybox.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,794评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,050评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,587评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,861评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,901评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,898评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,832评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,617评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,077评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,349评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,483评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,199评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,824评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,442评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,632评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,474评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,393评论 2 352