Linux内核中设置了一组用于实现系统功能的子程序,称为系统调用。系统调用和普通库函数调用非常相似明知是系统调用由操作系统核心提供,运行于核心态,而普通的函数调用由函数库或用户自己提供,运行于用户态。 一般的,进程是不能访问内核的,它不能访问内核所占用内存空间也不能调用内核函数。这被称为保护模式。为了和用户空间上运行的进程进行交互,内核提供一组接口。通过该接口应用程序可以访问硬件设备和其他操作系统资源。

实际上提供这组接口主要是为了保证系统稳定可靠,避免应用程序肆意妄为。 系统调用在用户空间和硬件设备之间添加一个中间层,也使得用户的应用程序可以不去管磁盘类型和介质,甚至不用去管文件所在的文件系统是什么类型。这方便了应用程序的可移植性。 在linux中系统调用是用户空间访问内核的唯一手段,除了异常和中断外。

一般情况下,应用程序通过应用程序接口API而不是直接通过系统调用来编程。因为应用程序使用的这种编程接口实际上并不需要和内核提供的系统调用一一对应。一个API接口可以实现成一个系统调用,也可以通过调用多个系统调用实现,也可以不使用任何系统调用。程序员可以不考虑系统调用而直接和API打交道。

系统调用:内核为用户进程提供的服务 提供用户模式的进程和硬件设备的接口; 保护对内核所管理的资源的访问,提高系统安全; 提高程序的可移植性; Linux系统调用在内核中全部以“sys_”开头,如sys_fork, sys_exit.

本文以内核版本为3.13.10为例演示hello world等级的调用,先看需要编译内核的系统调用

1.在kernel/sys.c中添加头文件#include<linux/linkage.h> 文件末尾添加自定义的系统调用函数:sys_mycall

内核版本为3.13.10
-->

2.在arch/x86/syscalls/syscall_64.tbl (32位系统则改为32)添加自定义系统调用号(在本人的机子上按顺序接下来是314)

3.在arch/x86/include/asm/syscalls.h中添加自己的系统调用函数声明

asmlinkage long sys_mycall(int num);

4.内核编译

记得加上-j4等来加快速度(即使是在第二次编译没有清理原目标文件的情况下也很耗时间(磁盘IO很耗时,固态硬盘应该很快吧)

5.编写用户态测试程序

int main(){     printf("The return value is:%d.\n",syscall(314,1234567));     return 0;}

编译为test_hello

6.测试

你可以更新内核,修改系统的启动项等。还可以使用虚拟机来测试,下面使用QEMU来测试(简便而且强大,可指定内核和文件系统来启动)

ubuntu下可从源下载QEMU,可顺便下一个linux-0.2 (wget wiki.qemu.org/download/linux-0.2.img)

然后将test_hello放到测试系统中,也许你想直接在测试系统中直接编译出test_hello,如果你没有现成的装有编译器的可测试系统,可用busybox来编译一个根文件系统

下面列出粗略步骤(但未包含编译工具及链接库):

make menuconfig时在Build Options选Build BusyBox as a static binary (no shared libs)确保不会对共享库产生依赖。

执行make CONFIG_PREFIX=your/dir install 将安装到制定目录,如rootfs/

dd if=/dev/zero of=rootfs.img bs=10240k count=1

mkfs -t ext3 rootfs.img

sudo mount -t ext3 -o loop rootfs.img rootfs

拷贝busybox到rootfs.img,将你的测试程序编译为静态的(gcc -static)拷贝至rootfs.img

$ cd rootfs
$ sudo mkdir dev
创建常用device(mknod 用于制作字符或块相关文件):
$sudo  cd dev
$ sudo mknod tty0 c 4 0
$ sudo mknod tty1 c 4 1
$ sudo mknod tty2 c 4 2
$ sudo mknod tty3 c 4 3
$ sudo mknod console c 5 1
$ sudo mknod null c 1 1
创建init启动脚本
/etc/inittab文件
$ sudo mkdir etc
$ cd etc/
$ sudo vim inittab
#This is the first script to run when startup
::sysinit:/etc/rc.d/rc.sysinit
::restart:/sbin/init
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a –r
$ sudo mkdir rc.d
$ cd rc.d/
$ sudo vim rc.sysinit
加入以下内容:
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
/bin/sh
$ sudo chmod a+x rc.sysinit
$ cd ../../../
根文件系统制作完成,umount rootfs
$ sudo umount rootfs.img

准备就绪,现在可以开始带根文件系统跑内核
qemu-system-x86_64 -hda rootfs.img -kernel /boot/vmlinuz-3.13.10 --append root=/dev/sda m=256 (看你的情况使用不同的命令)
可以看到linux在quem上跑起来了(刚启动可能需要回车才显示命令提示符,文件系统若是只读的可用mount -o rw,remount /重挂载,若启动时提示init等文件不可执行是你没有赋予它可执行权限。执行测试程序,下图中的call_static(执行时需要写全路径)。

linux内核增加系统调用--Beginner‘s guide的更多相关文章

  1. linux内核增加系统调用--Beginner's guide

    Linux内核中设置了一组用于实现系统功能的子程序,称为系统调用.系统调用和普通库函数调用非常相似明知是系统调用由操作系统核心提供,运行于核心态,而普通的函数调用由函数库或用户自己提供,运行于用户态. ...

  2. 给Linux内核增加一个系统调用的方法(转)

    作者:chenjieb520 给Linux内核增加一个系统调用的方法    为了更加好地调试linux内核,笔者的实验均在mini6410的arm板上运行的.这样做的原因,第一是因为本人是学嵌入式的, ...

  3. Linux之增加系统调用[内核编译]

    声明:如需引用或者摘抄本博文源码或者其文章的,请在显著处注明,来源于本博文/作者,以示尊重劳动成果,助力开源精神.也欢迎大家一起探讨,交流,以共同进步- 0.0 由于操作系统实验的缘故,有一个实验需要 ...

  4. 向linux内核增加一个系统调用-2(利用proc打印信息)

    添加系统调用,打印/proc中的系统信息 前面关于proc和内核态函数的东西可以对比代码来看. 参考 http://blog.csdn.net/kylin_fire_zeng/article/deta ...

  5. 深入理解Linux内核-系统调用

    系统调用:用户态进程向内核发出的,实现用户态进程调用硬件设备的函数或者中断:优点:使编程更容易,将用户从学习硬件设备的低级编程特性中解放:提高系统到安全性,内核在满足请求之前可以做正确性检查:提高可移 ...

  6. 向linux内核增加一个系统调用-1

    验证编辑编译内核的流程,并增加新的系统调用 注意:需要/目录至少10GB空间,/boot目录500MB空间 下载内核并解压 kernel下载 百度云搬运 密码: qc8b 进入 /usr/src目录 ...

  7. 《Linux内核分析》 week6作业-Linux内核fork()系统调用的创建过程

    一.进程控制块PCB-stack_struct 进程在操作系统中都有一个结构,用于表示这个进程.这就是进程控制块(PCB),在Linux中具体实现是task_struct数据结构,它主要记录了以下信息 ...

  8. 向linux内核加入系统调用新老内核比較

    2.6内核 1>改动linux-source-2.6.31/kernel/sys.c文件,在文件末尾加入系统响应函数.函数实现例如以下: asmlinkage int sys_mycall(in ...

  9. linux内核之系统调用nanosleep与pause()

    nanosleep()使得进程进入睡眠状态,指定时候后唤醒进程,sleep()基于其实现 asmlinkage long sys_nanosleep(struct timespec *rqtp, st ...

随机推荐

  1. Winform调用系统的剪切,复制,粘贴文件功能

    // <summary> /// 复制或剪切文件至剪贴板(方法) /// </summary> /// <param name="files"> ...

  2. 解决MWPhotoBrowser中的SDWebImage加载大图导致的内存警告问题

    下面两种现象,用同一种方法解决 1.解决MWPhotoBrowser中的SDWebImage加载大图导致的内存警告问题 2.突然有一天首页访问图片很慢,至少隔20多秒所有图片才会出来.(解析:app使 ...

  3. [转]源代码的管理和发布:以SVN为例

    FROM : http://ju.outofmemory.cn/entry/47277 前几天在微博吐槽了SVN的几个不爽的地方:.svn文件满天飞.分支管理的麻烦.不爽一般来说都是有过对比后才有如此 ...

  4. 由于 ASP.NET 进程标识对全局程序集缓存没有读权限,因此未能执行请求。错误: 0x80131902

    由于 ASP.NET 进程标识对全局程序集缓存没有读权限,因此未能执行请求.错误: 0x80131902 分类: c#2013-06-17 10:22 89人阅读 评论(0) 收藏 举报 ASP.NE ...

  5. node基础03:使用函数

    1.使用函数 //server.js var http = require("http"); var output = require("./output"); ...

  6. Theano2.1.16-基础知识之调试:常见的问题解答

    来自:http://deeplearning.net/software/theano/tutorial/shape_info.html Debugging Theano: FAQ and Troubl ...

  7. JS运动从入门到兴奋1

    hello,我是沐晴,一个充满了才华,却靠了照骗走江湖的前端妹子.在这个充满PS的年代,这你们都信,哈哈,废话不多说,今天要分享的是关注JS运动的知识.楼主一直认为,不管学习什么,核心思想才是王道,掌 ...

  8. jQuery Ajax 处理 HttpStatus

    今天同事碰到一个问题:当服务端Session失效后用ajax请求数据,页面端无法提示和执行跳转.我最先想到是,在后端用js输出一个跳转.发现输出没有效果,因为ajax是异步请求, 需要在success ...

  9. BroadcastReceive之ip拨号

    首先,新建一个类,继承于BroadcastReceive,然后去配置Manifest.xml <receiver android:name=".PhoneOnReceice" ...

  10. PLSQL Developer不支持Oracle 64位客户端解决方法

    问题描述: 在虚拟机同网段,搭建Oracle 11.2.04数据库64位的,本机操作系统Win10 x64和PLSQL 9.03,目前想利用PLSQL远程登录ORACLE数据库操作.当初用 insta ...