b97902HW 板


LINE

用 qemu + chroot 编译与测试 Linux Kernel 听说有人光是编译 Linux Kernel 就编译了 4 个小时, 也就是说若以 10/28 为 deadline 各位只剩下 42 次 修改档案的机会...。 -- 来自地下室的哀号 序言 我个人非常不喜欢编译 kernel,因为 kernel 是作业系统当中最重要 的部分。如果 kernel 编坏了可能无法开机,而且可能弄乱原有的作业 系统。 如果万不得已要自己编译,我通常会使用 fakeroot make-kpkg 之类 的指令把 kernel 编译成 Debian 套件,再用 dpkg -i 安装。日後要 移除也比较容易。 然而我日常的作业系统就是 Ubuntu,我不希望 OS Project 1 染指我 每天要使用的系统。而且一直重新开机测试修改成果也非常累,所以 我还是比较想要使用虚拟机器 (Virtual Machine)。 我这次要介绍二个工具:qemu-kvm 与 chroot,这二个工具都是用来 创造和原本作业系统相互隔离的环境,也各有长处与短处,所以我的 攻略会交互使用二个工具。 - qemu / qemu-kvm 这是一个虚拟机器,就像 VMWare, Virtual Box, Virtual PC 等软体, 可以用来模拟一台虚拟的电脑。 qemu 是使用 Dynamic Recompilation 模拟 CPU,不过这种技术执行速 度约为 Host CPU 的 20%。而 qemu-kvm 使用 paravirtualization,会 利用 Intel/Amd CPU 提供的虚拟机制加快模拟速度,执行速度约为 50~ 80%。 - chroot 这个是 Linux 之下的一个程式,可以帮我们把根目录替换成另一个目录, 就好像使用不同的 Linux(gcc、bash 甚至是 mv cp 等指令都会被换掉)。 在 chroot 环境下执行程式与一般环境执行程式无异,所以速度是 100%。 然而 chroot 不能完全隔离所有操作,所以要小心使用(避免使用 root 身分,或者是 sudo),以免影响原有的作业系统。 准备工作 1. 先有一套 Linux(推荐使用 Ubuntu Linux 或 Debian Linux) 以便使如 qemu-kvm 与 chroot 2. 准备一份 Linux 安装光碟映像档(我自己是用 Ubuntu 10.10) 3. 取得 qemu 与 qemu-kvm,在 Ubuntu Linux 之下,可以使用以 下指令取得: $ sudo apt-get install qemu qemu-kvm 4. 取得一份 Linux Kernel source code(我是用 2.6.36) http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.36.tar.bz2 准备子系统 1. 建立虚拟机器的硬碟档案(至少要 10Gb) $ dd if=/dev/zero of=disk.img bs=1 count=1 seek=10737418239 稍微说明一下:为了使用 chroot,我们不使用 qemu 特有可以动 态成长的硬碟格式。不过这里还是使用了一个小技巧:直接把档 案 seek 到 10Gb - 1byte 的地方,写入一个 byte 以节省时间。 2. 用 qemu 开启子系统 $ qemu -hda disk.img -m 1024 \ -cdrom ubuntu10.10.iso -boot d 参数说明: -hda 以此档案为主硬碟 -cdrom 以此档案为光碟映像档 -boot 开机选项 (c) 硬碟 (d) 光碟 -m 虚拟机器要有多少记忆体 (MB) 3. 依指示安装作业系统。不过要注意:在割硬碟的时候,把整块都割 给 root (/),不要留 swap。(要选「专家模式」然後手动切割) 4. 关机时,要我们取出光碟,此时就可以把 qemu 关掉了! 5. 重新开机 $ qemu -hda disk.img -m 1024 6. 在子系统安装必要的软体(打开「应用程式->附属应用程式->终端机」) \> sudo apt-get build-dep linux # 编译 linux 必备 \> sudo apt-get install libncurses5-dev # menuconfig 必备 7. 关机 在主系统挂载子系统的分割区 我想在主系统编译 kernel,所以我要把子系统的分割区挂载到主系 统上,再使用 chroot 把 root 切换到这一个分割区。 1. 先检查分割表计算分割区的 offset: $ sudo losetup /dev/loop0 disk.img $ sudo fdisk /dev/loop0 Command (m for help): p # 用 p 列出分割表的资讯 Disk /dev/loop0: 8589 MB, 8589934592 bytes 255 heads, 63 sectors/track, 1044 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Sector size (logical/physical): 512 bytes / 512 bytes # 记住 sector 的大小 I/O size (minimum/optimal): 512 bytes / 512 bytes Command (m for help): x # 进入专家模式 Expert command (m for help): p # 再列出分割表的资讯 Disk /dev/loop0: 255 heads, 63 sectors, 1044 cylinders Nr AF Hd Sec Cyl Hd Sec Cyl Start Size ID 1 80 32 33 0 86 53 993 2048 15955968 83 # 记住 start Expert command (m for help): q $ sudo losetup -d /dev/loop0 透过以上步骤,我们知道一个 sector 的大小是 512byte,另外 子系统的 root partition 是在 2048 个 sector,所以 offset 是 512 * 2048 = 1048576 (请根据你自己的情况加以修改) 2. 挂载子系统的 root 分割区 $ mkdir partition $ sudo losetup --offset 1048576 /dev/loop0 disk.img # 把档案当 loop device 备注:如果这一步有问题,可以试不同的 loop device:loop0 ~ loop7。 $ sudo mount /dev/loop0 partition # 挂载档案系统 备注:如果这一步有问题,大概是你的 offset 算错了! 3. 解压缩 Linux Kernel 的原始码 $ sudo chown username:username partition/usr/src 备注:暂时修改资料夹的权限。username 是你主系统档中 uid 为 1000 的使用者。一般来说应该就是你自己。 $ tar jxf linux-2.6.36.tar.bz2 -C partition/usr/src 说明:解压缩 Linux Kernel source code 到 partition/usr/src 资料夹之下。 $ sudo chown root:root partition/usr/src 备注:把权限改回来。 编译 linux 核心 1. 使用 chroot 进入子系统。要小心,chroot 的隔离不是绝对 安全的!只要有 root 权限,随时可以离开 chroot 的隔离 环境,所以要避免使用 root。 $ sudo chroot partition env -i TERM=xterm su username 参数说明:partition 是子系统的根目录,也就是我们要切换 的目标,後面是紧接着要执行的指令。 env -i 会把不相关的环境变数清掉。而 TERM=xterm 是因为 menuconfig 需要这个环境变数。 su 是把使用者切换成 username。这个 username 是子系统的 user,应该是你安装子系统时填入的名字。 2. 复制 Linux Kernel 设定档 \> cp /boot/config-2.6.35-22-generic .config 3. 执行 menuconfig。不用调整任何选项,直接 Exit 就可以了。 \> make menuconfig 4. 开始编译 Kernel 与模组 \> make -j4 bzImage modules 备注:根据每个人电脑的不同,要使用不同的 -jN。我的电 脑是双核心的 cpu,所以我觉得 -j4 很适合我。大家的电脑 应该都比我好,可以用更大的数字(但适量就好,并不是越大 越快)。 备注:用笔电的人记得把电源接上,让 CPU 可以全速工作。 备注:在我的笔电上这一步大概要 50 分钟到 1 小时。 安装新核心 编译完成之後,我们要安装核心。不过要安装核心,必需要有 sudo 的权限,所以在 chroot 的环境下不太安全,所以我们还是要改用 qemu 开机。 1. 离开 chroot 环境,并卸载子系统的分割区。 \> exit # 离开 chroot 环境 $ sudo umount partition # 卸载档案系统 (这可能会有一点久) $ sudo losetup -d /dev/loop0 # 解除档案与 loop device 之间的关连 2. 使用 qemu 开机 $ qemu -hda disk.img -m 1024 3. 开启终端机,依序执行以下指令 \> cd /usr/src/linux-2.6.36 \> sudo make modules_install install \> sudo mkinitramfs -o /boot/initrd.img-2.6.36 2.6.36 4. 修改 grub2 设定档,在 GRUB_HIDDEN_TIMEOUT=0 的前面加上 '#'。 \> sudo vi /etc/default/grub :%s/GRUB_HIDDEN_TIMEOUT=0/#GRUB_HIDDEN_TIMEOUT=0/g :wq 5. 更新开机选单 \> sudo update-grub2 6. 重新开机 小结 我们使用了二种创造隔离环境的方法:(1) 使用 qemu 当做我们的 虚拟机器 (2) 使用 chroot 隔离主系统与子系统。前者比较安全, 不过比较慢;後者比较快,但是比较不安全。 另外,一般我们要进入 chroot 的环境,我们要 losetup、mount、 chroot,使用完必之後,要再 exit、umount、losetup -d。程序 很烦锁,而且如果没有 umount、losetup -d,就执行 qemu 就会 有很可怕的结果(很可怕不要问)。所以我写了一个 shell script 自动执行这些步骤: http://w.csie.org/~b97073/B/enter-partition.sh.txt 下载後,修改 USERNAME、PARTITION_OFFSET 再 chmod +x,即可 使用 ./enter-partition.sh.txt。看到 leaving successfully 才是正常结束。 修改作业系统与重新安装 1. $ ./enter-partition.sh # 进入 chroot 2. \> cd /usr/src/linux-2.6.36 # 进入 source code 的资料夹 3. 修改 kernel 的 source code。 (1) kernel 资料夹之下建立 myservice.c 这个档案,并输入 助教给的程式: #include <linux/linkage.h> #include <linux/kernel.h> asmlinkage int sys_myservice(int arg1) { printk("my service is invoked!\n"); return arg1 * 10; } (2) 打开 arch/x86/include/asm/unistd_32.h 找到最後一个 #define __NR_... 在它的最面加上 #define __NR_myservice 341 。然後把下面的 NR_syscalls 改成 342。 (3) 打开 arch/x86/kernel/syscall_table_32.S,直接移到 最後一行,加上 .long sys_myservice (4) 打开 include/linux/syscalls.h,移到最後,#endif 之前,加上 asmlinkage int sys_myservice(int arg1); (5) 打开 kernel/Makefile,在一开始的地方加上 obj-y += myservice.o 4. \> make -j4 bzImage modules 备注:如果有修改 arch/x86/include/asm/unistd_32.h, 那几乎所有的 source code (bzImage 与 modules) 都要重 新编译,又是一个小时... ,所以要尽量避免。 备注:如果只改 kernel/myservice.c kernel/signal.c include/linux/syscalls.h 重新编译的时间不超过 10 分钟。 备注:没事千万不要 make clean!! 5. \> exit # 离开 chroot 6. $ qemu -hda disk.img -m 1024 7. \> cd usr/src/linux-2.6.36 \> sudo make modules_install install # 安装新的 os \> sudo update-initramfs -u -k 2.6.36 # 更新 initramfs \> sudo reboot 8. 写一个测试用的程式: #include <stdio.h> #include <stdlib.h> #define _GNU_SOURCE #include <unistd.h> #include <sys/syscall.h> #define __NR_myservice 341 int main(int argc, char *argv[]) { int num = (argc > 1) ? atoi(argv[1]) : 1234; printf("%d\n", (int)syscall(__NR_myservice, num)); return EXIT_SUCCESS; } 然後怀着敬畏的心情,compile 并执行它!祝你好运! 9. Project 1 的部分,就如投影片所说,要在 SYSCALL_DEFINE2(kill 加料,而 sent signal 可以在 __send_signal 加料。 Q & A Q: 喂 logan,我装了 qemu-kvm 之後,Virtual Box 就坏掉了, 你要负责! A: qemu-kvm 相冲!所以如果你要用 Virtual Box 必需要把 qemu 与 qemu-kvm 移除。 $ sudo apt-get purge qemu qemu-kvm Q: 怎麽看 printk 的结果? A: sudo dmesg | tail -n 10 Q: 为什麽我按下 Alt-F4 之後,qemu 就关掉了,我要关的是里面的 视窗呀! A: 按下左方的 Ctrl+Alt 可以锁定键盘还有滑鼠。 结语 这份作业蛮有趣的! 如果有人在结报上提到这篇文章我会很高兴的。 ^^ \ --



※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 140.112.30.131 ※ 编辑: LoganChien 来自: 140.112.30.131 (10/22 06:19)
1F:推 purincess:推一个! 10/22 07:32
2F:推 davidpanda:L大强者救援文出现了 @.@! 10/22 08:18
3F:推 fereshte:大强者!!! 10/22 09:28
4F:推 jimmyken793:Q&A第一个的暂时性解法:sudo rmmod kvm-intel 10/22 09:33
5F:→ jimmyken793:如果是intel cpu的话 10/22 09:34
6F:推 jlg79531:谢谢Logan!! 10/22 10:18
7F:推 lmr3796:救援来了! 10/22 11:03
8F:推 hanabi:有看有推!! 10/22 18:56
9F:推 andy74139:推!! :) 10/23 09:49
※ 编辑: LoganChien 来自: 61.224.103.133 (10/23 12:03)
10F:推 averangeall:有看有推!!! 12/16 12:43







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:WOW站内搜寻

TOP