原文地址:https://blog.csdn.net/qq_34247099/article/details/50949720
写在前面的话:
本人大二,东南大学一个软工狗,正在修一门名为《操作系统原理》的坑爹课!前几天做一个实验:编译Linux内核并向其增加一个系统调用。这个实验实在是太让人无语了,各种坑!昨天这个时候,我还在苦苦煎熬中。在今天凌晨四点才做好。为了让其他人少走一些弯路,鄙人就把自己的经验以及教训写下来。里面会有一些不足,希望大家多多指教~

废话不多说,那就开始吧:
一、实验前的准备:
Vmware + ubuntu10.10 (32位)+ linux-2.6.32.71.tar.xz
安装虚拟机教程:http://jingyan.baidu.com/article/90895e0f95a07564ec6b0bc7.html
说明:ubuntu 10.10是我试验的最后一个,也是最后成功的那个。当然,更推荐ubuntu 10.04,因为这个支持sudo apt-update 少了一些麻烦。 而由于10.10不支持更新,故我另外新下了linux 2.6.32.71 先将这个文件拖入虚拟机桌面。

附: ubuntu10.10百度网盘分享:链接:http://pan.baidu.com/s/1bnNr8dD 密码:ybg3
        linux-2.6.32.71.tar.xz 百度网盘分享:链接:http://pan.baidu.com/s/1c1cOOtq 密码:epu9(可能已经失效,大家可以去某度上面进行下载。网上资源很多,造成的不便,很抱歉~)
二、解压内核
1、先打开安装好的ubuntu 进入终端 :在桌面按ctrl+alt+T
2、输入sudo su 获取root权限:(会出现一个输入密码的一个命令行,在终端输入密码时,是不显示星号的。你只管把密码输入回车就行了!用惯了window的小伙伴可能会有些不适应)最后如图:

3、先把下载好的内核复制到 /usr/src 文件夹中 : 
      终端输入 cd Desktop(定位到桌面) 回车 ; cp  linux-2.6.32.71.tar.xz  /usr/src 回车
4、解压内核 依次输入以下命令回车执行
      cd /usr/src ;
   xz -d linux-2.6.32.71.tar.xz
     tar xvf  linux-2.6.32.71.tar

三、增加系统调用
1、
打开sys.c文件。

gedit /usr/src/linux-2.6.32.71/kernel/sys.c

2、

在文件末尾增加系统调用。

asmlinkage intsys_mycall(int number)

{

 printk("My Student No. is XXXXX,and My Name is XXXXX*** !");

 return number;

}

注:printk就是系统调用输出一行文字,你可以自定义里面内容,便于最终检验。
3、

 注册系统调用:

gedit /usr/src/linux-2.6.32.71/arch/x86/kernel/syscall_table_32.S

在.long 类型文件末尾添加:

.longsys_mycall

并且按照顺序记住它属于第几个系统调用,在本机中为337。

4、
gedit /usr/src/linux-2.6.32.71/arch/x86/include/asm/unistd_32.h

在一系列#define __NR_之后添加:

 

define __NR_mycall 337

在这里就需要用到之前记住的数字了。

四、编译内核
ps:深吸一口气,前面做的只是准备工作!下面才是真正的开始!打好精神,真正的挑战在下面!
下面的记得一定要一步一步都要做!不要漏掉一步!!!!
进入解压目录:

cd /usr/src/linux-2.6.32.71

make mrproper

make clean

make oldconfig

make bzImage  (这个过程和下面的过程非常非常非常长,亲测,建议泡杯茶,或是看个电影,没有两个小时不行)

make modules

make modules_install

五、拷贝内核
经过了漫长的等待,我们终于到了这一步。
先检验一下我们的结果:
 

 首先查看一下编译好的内核版本,以便命名 打开 /lib/modules  里面应该多了一个纯数字不带"generic"的文件夹,那就是新内核版本号,我们的是2.62.32.71 如下所示:

有了这个就代表前面的没有什么错误了。

接着,就在终端输入: 
cp /usr/src/linux-2.6.32.71/arch/i386/boot/bzImage  /boot/vmlinuz-2.6.32.71-mykernel

六、创建initrd文件
mkinitramfs-o /boot/initrd.img-2.6.32.71

七、更新grub引导表
进行到这一步,也许你感觉到自己差不多了,毕竟都这么久了,你也许有些困了,有些疲惫,但是,我告诉你,最难最容易出错的,就在当前这一步!建议你先休息一下,下面需要你投入百分之百的注意力去做,若是出错,你可是要全部重新开始的!

  1. gedit /boot/grub/grub.cfg

  2. 在打开的文件中找到类似如下的字段,并复制并粘贴在前面:

但必须在同一个

 BEGIN /etc/grub.d/10_linux ### 

       ……  

 END /etc/grub.d/10_linux 

里面:

字段如下:
menuentry 'Ubuntu, with Linux 2.6.35-22-generic' --class ubuntu --class gnu-linux --class gnu --class os {
recordfail
insmod part_msdos
insmod ext2
set root='(hd0,msdos1)'
search --no-floppy --fs-uuid --set 0efd72ba-ba85-470f-8c21-ab68730ca8c9
linux /boot/vmlinuz-2.6.35-22-generic root=UUID=0efd72ba-ba85-470f-8c21-ab68730ca8c9 ro   quiet splash
initrd /boot/initrd.img-2.6.35-22-generic
}
menuentry 'Ubuntu, with Linux 2.6.35-22-generic (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os {
recordfail
insmod part_msdos
insmod ext2
set root='(hd0,msdos1)'
search --no-floppy --fs-uuid --set 0efd72ba-ba85-470f-8c21-ab68730ca8c9
echo 'Loading Linux 2.6.35-22-generic ...'
linux /boot/vmlinuz-2.6.35-22-generic root=UUID=0efd72ba-ba85-470f-8c21-ab68730ca8c9 ro single 
echo 'Loading initial ramdisk ...'
initrd /boot/initrd.img-2.6.35-22-generic
}

将粘贴后字段里面的
 linux    /boot/vmlinuz-2.6.35-22-generic      initrd    /boot/initrd.img-2.6.35-22-generic  改成你的内核文件地址和initrd 地址:
 linux   /boot/vmlinuz-2.6.32.71-mykernel    initrd    /boot/initrd.img-2.6.32.71

这一步特别无聊但又必须认认真真做,要不然你就前功尽弃,别问我怎么知道的,我要是牢记这句话,不会到四点才睡觉 ( ╯□╰ )!! 建议全部改完之后,检查几遍。笔者以及室友们都在这步出错,以至于不得不重新开始。全部完成如图所示:

 红框是改过之后的,篮框里面的是你需要复制的内容 可以看到 ,两者在同一个###BEGIN /etc/**** 里面 黄色下划线部分
(图丑见谅)

八、收尾工作
好了,你若已经检查完毕上面的一切工作,那么,扫尾工作就开始了,这时候,也莫要放松 一步一步来,喝点开水,长呼口气,一步一步来,下面的一步一步落实:
cd /boot

cp initrd.img-2.6.32.71 initrd-2.6.32.71.old

depmod–a

update-initramfs-k 2.6.32.71 –c

cd /tmp

gzip-dc /boot/initrd.img-2.6.32.71| cpio –id

touch lib/modules/2.6.32.71/modules.dep

find./ | cpio -H newc -o > /boot/initrd.img-2.6.32.71.new

gzip /boot/initrd.img-2.6.32.71.new

cd /boot

mvinitrd.img-2.6.32.71.new.gz initrd.img-2.6.32.71

九、重启
终于到了验证结果的一步了,此时你要克制一下自己的激动心情,在终端键入 reboot 点击回车。慢慢等待一会,若是你重启成功,那么恭喜你,你已经要看到胜利的曙光啦!
重新进入终端,获取权限,过程前面有讲,不再重复。在终端键入 uname -a 回车
此时若是看到
linux-2.6.32.71,说明已经成功!

如下:

若是看到这个,你就可以大叫一声庆祝一下了,你已经成功啦!!!!

十、测试自定义系统调用
打开终端,键入gedit,打开gedit工具,继续键入如下代码:

include<stdio.h>

int main()

{

       syscall(337, 1);

       return 0;

}

保存为mytest.c

再继续在终端中键入

gcc-o mytest mytest.c(编译C程序)

之后 ./mytest 。

点击运行编译出来的程序,此时并不会显示出效果,在终端中键入dmesg –c查看系统调用信息。

此时,你可以看到

说明之前写的sys_mycall调用成功!
到这一步,算是全部成功啦!!庆祝一下,去装个逼吧~~~~
 
写在最后的话:

由于笔者是新手,里面的步骤有些显得很笨重,希望大手们看到之后多多指教!谢谢!!
另外,做这个实验一定要有耐心,若是你做的时候一直很小心,每一步都认真做,那么你一次就可以成功!!别像笔者这样做了不知多少遍。
最后,祝大家成功!!   有不足,也希望大家指出,谢谢@~@
 
ps:
参考文档:http://wenku.baidu.com/view/40af3b6727d3240c8447efd8.html?qq-pf-to=pcqq.c2c

第一篇博文,谢谢大家的浏览o(^▽^)o
————————————————
版权声明:本文为CSDN博主「GloryBossy」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_34247099/article/details/50949720

[转载]Linux内核编译的更多相关文章

  1. 运行在TQ2440开发板上以及X86平台上的linux内核编译

    一.运行在TQ2440开发板上的linux内核编译 1.获取源码并解压 直接使用天嵌移植好的“linux-2.6.30.4_20100531.tar.bz2”源码包. 解压(天嵌默认解压到/opt/E ...

  2. linux内核编译环境配置

    linux内核编译环境配置 如果不是编译内核,只需要安装与内核相匹配的kernel-devel开发包即可.即是/lib/modules/`uname -r`/build -> /usr/src/ ...

  3. Linux内核编译与安装

    2013-04-16    Linux内核介绍  Linux内核是一个用C语言写成的,符合POSIX标准的类Unix操作系统.内核是操作系统中最基本的一部分,提供了众多应用程序访问计算机硬件的机制.L ...

  4. Lab1:Linux内核编译及添加系统调用(详细版)

    实验一:Linux内核编译及添加系统调用(HDU) 花了一上午的时间来写这个,良心制作,发现自己刚学的时候没有找到很详细的,就是泛泛的说了下细节地方也没有,于是自己写了这个,有点长,如果你认真的看完了 ...

  5. Linux内核编译、安装流程

    原文链接:https://blog.csdn.net/qq_28437139/article/details/83692907 此处只讲linux内核编译步骤至于安装虚拟机,安装ubuntu操作系统请 ...

  6. Linux内核编译完整过程

    Linux内核编译完整过程 通过网上的资料我自己的实际内核编译,我把对Linux内核编译的过程写在这里,也许对其他的Linux爱好者的编译学习有些帮助,其中很大部分是网上的资料,另外就是我在实际编译过 ...

  7. Linux 内核 编译模块

    背景: 由于调试内核或者由于分区大小限制,有时候内核组件不一定完全需要编进内核中. 所以,在开发中经常将内核组件编译成为模块,等到在恰当的时机加载. 概览: Linux内核模块的编译方法有两种: 1. ...

  8. Linux内核编译配置脚本

    环境 宿主机平台:Ubuntu 16.04.6 目标机:iMX6ULL Linux内核编译配置脚本 在linux开发过程中熟练使用脚本可以大大简化命令行操作,同时对于需要经常重复操作的指令也是一种备忘 ...

  9. 转载 linux内核 asmlinkage宏

    转载http://blog.chinaunix.net/uid-7390305-id-2057287.html 看一下/usr/include/asm/linkage.h里面的定义:#define a ...

随机推荐

  1. el-input和和filter结合实现实时搜索

    <el-input placeholder="请选择日期" clearable prefix-icon="el-icon-search" v-model= ...

  2. Mongo rs

    概念 rs中存储了每一次对mongo数据库的CUD操作,对rs的大小进行resize. 主要有两种方法: 在未开启过rs的情况下,修改配置文件 已使用rs一段时间后,发现rs太大,重新进行大小配置 启 ...

  3. sqli-labs(4)

    sqli-libs(4)通关过程 0x01爱之初体验 首先我们进行注入试探 发现我们的单引号 回显事正常的 双引号回显反而是错误的 查看源码我们发现 多了一个给id赋值的语句 我们在php上面执行一下 ...

  4. hdu 4763 看毛片(单纯next数组的应用--纯正O(n))

    因为需要负责队内的字符串题,开始刷,做到这道,开始想不出来,上网找题解, 然后就惊了,为什么你们这么暴力都可以过的啊,1e6啊,后来又想了下会做了 贴下代码 #include <iostream ...

  5. Understanding the Transform Function in Pandas

    Understanding the Transform Function in Pandas 来源 What is transform? 我在 Python Data Science Handbook ...

  6. akka 的集群访问方式

    akka  中采用startProxy分区代理 访问 ,跟使用shardRegion 来访问的区别 这两种访问方式是不是重了呢. 而另外这是一个单例代理 private fun startUniver ...

  7. 20175212童皓桢 实验三敏捷开发与XP实践实验报告

    20175212童皓桢 实验三敏捷开发与XP实践实验报告 实验内容 XP基础 XP核心实践 相关工具 实验步骤 一.Code菜单功能的研究 Move Line/statement Down/Up:将某 ...

  8. C语言中的!!

    C语言中!!的作用是?看例子: #include <stdio.h> int main() { ; printf("test=%d !test=%d !!test=%d\n&qu ...

  9. ES6 正则的扩展(待细读)

    1.RegExp构造函数 在 ES5 中,RegExp构造函数的参数有两种情况. a.参数是字符串,这时第二个参数表示正则表达式的修饰符(flag) var regex = new RegExp('x ...

  10. Scala学习(一)——基础语法

    Scala语言是一种面向对象语言,结合了命令式(imperative)和函数式(functional)编程风格,其设计理念是创造一种更好地支持组件的语言. 特性 多范式(Multi-Paradigm) ...