第一步,用qemu启动linux内核,从跑个Helloworld开始

时间:2021-11-14 06:36:15
       老生长谈的内容了,就是自己编译内核,然后制作initramfs,在用qemu跑
起来。不过在这之前先跑个helloworld玩玩。

顺便我在学校写博客的笔记本系统是ubuntu16.04,在实习单位玩的时候用的系统是centos7,两个不同的地方我会尽量说明,当然有些地方我自己也不是很清楚就是了。

编译内核

#  建一个目录
$  mkdir build
# 首先當然是去下一個linux內核,地址, 我这里选的版本是3.10.104
$ wget https://cdn.kernel.org/pub/linux/kernel/v3.x/linux-3.10.104.tar.xz
#  解压
$ tar xvf linux-3.10.104.tar.xz
$ cd linux-3.10.104
$ make menuconfig


  进行内核选项配置,其中的内容非常多,我也没看完,但是由于这次我们什么都用不到,也不用编译模块,可以把Device Driver里绝大部分和一些不常用的东西都勾选掉.具体配置自己参照网上吧,也可以直接用别人配好的设置直接覆盖.  为了方便务必把debug info 勾选上.
#    -j8的选项是为了让编译更快点,一般这数字选择为cpu核数*2.$    make -j8 
# ls -la linux-3.10.104/arch/x86_64/boot/bzImage
lrwxrwxrwx 1 seijia seijia 22 12月 17 23:52 linux-3.10.104/arch/x86_64/boot/bzImage -> ../../x86/boot/bzImage
$ cp linux-3.10.104/arch/x86_64/boot/bzImage ..
#  安装qemu,可以自己去下源码安装,我比较懒直接用apt-get安装了
$   sudo apt-get install qemu


制作initrd
/*hello.c*/#include <stdio.h>void main(){    printf("Hello World\n");    printf("Hello World\n");    printf("Hello World\n");  /*强制刷新输出,不然可能打印不出来*/    fflush(stdout);    while(1);}



initrd吧,全称是initial ramdisk,在内核启动的时候会先去加载的一种文件系统.


$    cd ..
# 使用静态编译链接.
$ gcc -static -o helloworld hello.c
# 将helloworld制作成cpio
$ echo helloworld | cpio -o --format=newc > rootfs
1776 blocks
$ ls -la rootfs
-rw-rw-r-- 1 seijia seijia 909312 12月 21 13:15 rootfs
# 使用qemu进行启动
$ qemu-system-x86_64 \
-kernel ./bzImage \
-initrd ./rootfs \
-append "root=/dev/ram rdinit=/helloworld"


  qemu的-kernel 和-initrd能够绕过bootload直接对指定的kernel和ramdisk进行加载.用-append进行额外的选项配置,在这里我们把根目录直接设置成内存,启动的init程序设置成放进去的helloworld.

第一步,用qemu启动linux内核,从跑个Helloworld开始
最后结果,因为while(1),启动会一直停在这里.
当然只有helloworld我们是什么都做不了的.这时候就需要busybox了,用它启动之后就能使用绝大多数的linux命令了.如果有不对的地方欢迎指出,不过我这么一个小博客也没人看吧(敲打
第一次这个编辑器花了很久才会用,第一次写格式全崩了...