导航:首页 > 编程系统 > 系统调用提纲linux内核之旅

系统调用提纲linux内核之旅

发布时间:2023-06-08 08:58:43

❶ 如何编译linux内核内核 mint系统实现系统调用

《linux内核设计与实现》读书笔记(五)-系统调用主要内容:什么是系统调用linux上的系统调用实现原理一个简单的系统调用的实现1ernel/sys.c我在sys.c中追加了2个函数:sys_foo和sys_bar如果是在x86_64的内核中增加一个系统调用

❷ 如何调用Linux内核函数

注意看这个文件
sysdeps/unix/sysv/linux/syscalls.list
里面记录着系统调用的名字和一些属性,具体我也没有研究过,不懂。
再看select的实现,很让人惊讶,一旦使用,结果就是“报错“。
int
__select (nfds, readfds, writefds, exceptfds, timeout)
int nfds;
fd_set *readfds;
fd_set *writefds;
fd_set *exceptfds;
struct timeval *timeout;
{
__set_errno (ENOSYS);
return -1;
}
libc_hidden_def (__select)
stub_warning (select)
weak_alias (__select, select)
这是因为glibc并没有实现系统调用,而是调用系统调用,
更进一步,连调用系统调用都没有一个个实现,而是使用了通用的办法,
理由很简单,所有的系统调用在linux内核头文件里都能找到,
所有的系统调用参数类型就那么几种,参数个数也是有限的,
因此没有必要针对所有的系统调用一一封装,
于是就有了这个list文件,自动生成调用系统调用的函数,
如果生成失败,也就是你看到的“报错”。
符号是有强弱的,当自动生成成功的时候,“报错”的弱符号就被忽略了。
当你在glibc中找到一个系统调用的封装源码,是以下原因,
1. 编译的目标系统不支持这个系统调用,所以自己用另一种方式实现了。
2. 这个系统调用无法使用通用的自动生成方式生成,用特化的方式覆盖。
3. 针对这个系统调用做了特别的优化。
4. 其它可能的原因。
具体可以留意
SYSCALL, PSEUDO, DO_CALL, INLINE_CALL 等名字
这两个文件是重点所在
sysdeps/unix/i386/sysdep.h
sysdeps/unix/i386/sysdep.S
要搞清楚具体的自动生成过程,恐怕得研究glibc自身的编译过程了

❸ 什么是系统调用系统调用是通过什么方式陷入内核态的

学习Linux内核的系统调用,理解、掌握Linux系统调用的实现框架、用户界面、参数传递、进入/返回过程。
实验内容
本实验分两步走。
第一步,在系统中添加一个不用传递参数的系统调用;执行这个系统调用,使用户的uid等于0。显然,这不是一个有实际意义的系统调用。我们的目的并不是实用不实用,而是通过最简单的例子,帮助熟悉对系统调用的添加过程,为下面我们添加更加复杂的系统调用打好基础。
第二步,用kernel mole机制,实现系统调用gettimeofday的简化版,返回调用时刻的日期和时间。

实验指导
1.一个简单的例子
在我们开始学习系统调用这一章之前,让我们先来看一个简单的例子。就好像哪个经典的编程书上都会使用到的例子一样:

1: int main(){
2: printf(“Hello World!\n”);
3: }

我们也准备了一个例子给你:

1: #include <linux/unistd.h> /* all system calls need this header */
2: int main(){
3: int i = getuid();
4: printf(“Hello World! This is my uid: %d\n”, i);
5: }

这就是一个最简单的系统调用的例子。与上面那个传统的例子相比,在这个例子中多了2行,他们的作用分别是:
第一行:包括unistd.h这个头文件。所有用到系统调用的程序都需要包括它,因为系统调用中需要的参数(例如,本例中的“__NR_getuid”,以及_syscall0()函数)包括在unistd.h中;根据C语言的规定,include <linux/unistd.h>意味着/usr/include/linux目录下整个unistd.h都属于Hello World源程序了。
第三行:进行getuid()系统调用,并将返回值赋给变量i。
好了,这就是最简单的一个使用了系统调用的程序,现在你可以在你的机器上试一试它。然后我们一起进入到系统调用的神秘世界中去。

❹ 在Linux中产生一个系统调用以及怎样通过往Linux内核中增加一个新函数从而在该内核

若要在kernel里面新增加一个自己的syscall,大致需要这么几个步骤:

a,新增自己syscall的代码,并修改相应makefile;

b,修改相应头文件,分配自己的系统调用号;

c,系统调用通过中断加查表的方式实现,所以需要在系统调用表里面增加相关的项目,这需要修改相关的汇编源文件;

d,重新编译内核,并写测试程序测试新增的syscall;

注意几点:

1,上述步骤所要修改的文件/位置等对不同处理器架构来说,不尽相同;

2,对于应用层的测试代码来说,在2.6.20版本之前,可以使用相应的_syscallN宏;

但是2.6.20版本后,这些宏已经被从kernel中去掉了,你需要使用应用层的syscall函数

来测试。

你可以在自己的syscall实现文件中加上EXPORT_SYMBOL/EXPORT_SYMBOL_GPL

等宏来导出你的全局变量或者函数,导出后,另外的模块或者其他内核代码就可以使用

这些变量和函数。

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

杭州巨立安(JulianTec)是杭州市场上

唯一由资深研发工程师所创办的机构。所以:

就专业程度和实在程度而言,杭州巨立安(JulianTec)

是您在arm架构下学习嵌入式Linux研发的上佳指导!

❺ Linux内核与内核函数与操作系统,系统调用,这几者的联系是啥

实现内核各种功能的就是内核函数,而操作系统是有:uboot、内核、文件系统和应用程序组成的。系统调用是操作系统提供给用户层或者说是应用层的一个接口,因为应用层是不能直接访问内核的(内核态)。

❻ 如何在linux内核中添加系统调用

一、Linux0.11下添加系统调用:

我在bochs2.2.1中对linux0.11内核添加了一个新的系统调用,步骤如下:
1./usr/src/linux/include/unistd.h中添加:#define __NR_mytest 87
然后在下面声明函数原型:int mytest();
2./usr/src/linux/include/linux/sys.h中添加:extern int sys_mytest();
然后在sys_call_table中最后加上sys_mytest;
3.在/usr/src/linux/kernel/sys.c中添加函数实现如下:
int sys_mytest(){
printk("This is a test!");
return 123;
}
4.在/usr/src/linux/kernel/system_call.s中对系统调用号加1(原来是86改成了87)
5.然后到/usr/src/linux目录下编译内核make clean; make Image
6. cp /usr/src/linux/include/unistd.h /usr/include/unistd.h
7. reset bochs
8. 在/usr/root中生成test.c文件如下:
#define __LIBRARY__
#include <unistd.h>
_syscall0(int,mytest)
int main(){
int a;
a = mytest();
printf("%d", a);
return 0;
}
9.然后gcc test.c编译之后运行a.out,前面所有步骤都通过,但是每次调用都是返回-1,然后我查过errno为1(表示操作不允许),就不知道为什么了?
系统知道的高手们能够告知一下,不胜感激!这个问题困扰我很久了!

二、新Linux内核添加系统调用

如何在Linux系统中添加新的系统调用
系统调用是应用程序和操作系统内核之间的功能接口。其主要目的是使得用户可以使用操作系统提供的有关设备管理、输入/输入系统、文件系统和进程控制、通信以及存储管理等方面的功能,而不必了解系统程序的内部结构和有关硬件细节,从而起到减轻用户负担和保护系统以及提高资源利用率的作用。

Linux操作系统作为自由软件的代表,它优良的性能使得它的应用日益广泛,不仅得到专业人士的肯定,而且商业化的应用也是如火如荼。在Linux中,大部分的系统调用包含在Linux的libc库中,通过标准的C函数调用方法可以调用这些系统调用。那么,对Linux的发烧友来说,如何在Linux中增加新的系统调用呢?
1 Linux系统调用机制

在Linux系统中,系统调用是作为一种异常类型实现的。它将执行相应的机器代码指令来产生异常信号。产生中断或异常的重要效果是系统自动将用户态切换为核心态来对它进行处理。这就是说,执行系统调用异常指令时,自动地将系统切换为核心态,并安排异常处理程序的执行。Linux用来实现系统调用异常的实际指令是:

Int $0x80

这一指令使用中断/异常向量号128(即16进制的80)将控制权转移给内核。为达到在使用系统调用时不必用机器指令编程,在标准的C语言库中为每一系统调用提供了一段短的子程序,完成机器代码的编程工作。事实上,机器代码段非常简短。它所要做的工作只是将送给系统调用的参数加载到CPU寄存器中,接着执行int $0x80指令。然后运行系统调用,系统调用的返回值将送入CPU的一个寄存器中,标准的库子程序取得这一返回值,并将它送回用户程序。

为使系统调用的执行成为一项简单的任务,Linux提供了一组预处理宏指令。它们可以用在程序中。这些宏指令取一定的参数,然后扩展为调用指定的系统调用的函数。

这些宏指令具有类似下面的名称格式:

_syscallN(parameters)

其中N是系统调用所需的参数数目,而parameters则用一组参数代替。这些参数使宏指令完成适合于特定的系统调用的扩展。例如,为了建立调用setuid()系统调用的函数,应该使用:

_syscall1( int, setuid, uid_t, uid )

syscallN( )宏指令的第1个参数int说明产生的函数的返回值的类型是整型,第2个参数setuid说明产生的函数的名称。后面是系统调用所需要的每个参数。这一宏指令后面还有两个参数uid_t和uid分别用来指定参数的类型和名称。

另外,用作系统调用的参数的数据类型有一个限制,它们的容量不能超过四个字节。这是因为执行int $0x80指令进行系统调用时,所有的参数值都存在32位的CPU寄存器中。使用CPU寄存器传递参数带来的另一个限制是可以传送给系统调用的参数的数目。这个限制是最多可以传递5个参数。所以Linux一共定义了6个不同的_syscallN()宏指令,从_syscall0()、_syscall1()直到_syscall5()。

一旦_syscallN()宏指令用特定系统调用的相应参数进行了扩展,得到的结果是一个与系统调用同名的函数,它可以在用户程序中执行这一系统调用。
2 添加新的系统调用
如果用户在Linux中添加新的系统调用,应该遵循几个步骤才能添加成功,下面几个步骤详细说明了添加系统调用的相关内容。

(1) 添加源代码

第一个任务是编写加到内核中的源程序,即将要加到一个内核文件中去的一个函数,该函数的名称应该是新的系统调用名称前面加上sys_标志。假设新加的系统调用为mycall(int number),在/usr/src/linux/kernel/sys.c文件中添加源代码,如下所示:
asmlinkage int sys_mycall(int number)
{
return number;
}
作为一个最简单的例子,我们新加的系统调用仅仅返回一个整型值。

(2) 连接新的系统调用

添加新的系统调用后,下一个任务是使Linux内核的其余部分知道该程序的存在。为了从已有的内核程序中增加到新的函数的连接,需要编辑两个文件。

在我们所用的Linux内核版本(RedHat 6.0,内核为2.2.5-15)中,第一个要修改的文件是:

/usr/src/linux/include/asm-i386/unistd.h

该文件中包含了系统调用清单,用来给每个系统调用分配一个唯一的号码。文件中每一行的格式如下:

#define __NR_name NNN

其中,name用系统调用名称代替,而NNN则是该系统调用对应的号码。应该将新的系统调用名称加到清单的最后,并给它分配号码序列中下一个可用的系统调用号。我们的系统调用如下:

#define __NR_mycall 191

系统调用号为191,之所以系统调用号是191,是因为Linux-2.2内核自身的系统调用号码已经用到190。

第二个要修改的文件是:

/usr/src/linux/arch/i386/kernel/entry.S

该文件中有类似如下的清单:
.long SYMBOL_NAME()

该清单用来对sys_call_table[]数组进行初始化。该数组包含指向内核中每个系统调用的指针。这样就在数组中增加了新的内核函数的指针。我们在清单最后添加一行:
.long SYMBOL_NAME(sys_mycall)

(3) 重建新的Linux内核

为使新的系统调用生效,需要重建Linux的内核。这需要以超级用户身份登录。
#pwd
/usr/src/linux
#

超级用户在当前工作目录(/usr/src/linux)下,才可以重建内核。

#make config
#make dep
#make clearn
#make bzImage

编译完毕后,系统生成一可用于安装的、压缩的内核映象文件:

/usr/src/linux/arch/i386/boot/bzImage
(4) 用新的内核启动系统
要使用新的系统调用,需要用重建的新内核重新引导系统。为此,需要修改/etc/lilo.conf文件,在我们的系统中,该文件内容如下:

boot=/dev/hda
map=/boot/map
install=/boot/boot.b
prompt
timeout=50

image=/boot/vmlinuz-2.2.5-15
label=linux
root=/dev/hdb1
read-only

other=/dev/hda1
label=dos
table=/dev/had

首先编辑该文件,添加新的引导内核:
image=/boot/bzImage-new
label=linux-new
root=/dev/hdb1
read-only

添加完毕,该文件内容如下所示:
boot=/dev/hda
map=/boot/map
install=/boot/boot.b
prompt
timeout=50

image=/boot/bzImage-new
label=linux-new
root=/dev/hdb1
read-only

image=/boot/vmlinuz-2.2.5-15
label=linux
root=/dev/hdb1
read-only

other=/dev/hda1
label=dos
table=/dev/hda

这样,新的内核映象bzImage-new成为缺省的引导内核。为了使用新的lilo.conf配置文件,还应执行下面的命令:
#cp /usr/src/linux/arch/i386/boot/zImage /boot/bzImage-new

其次配置lilo:

# /sbin/lilo

现在,当重新引导系统时,在boot:提示符后面有三种选择:linux-new 、linux、dos,新内核成为缺省的引导内核。
至此,新的Linux内核已经建立,新添加的系统调用已成为操作系统的一部分,重新启动Linux,用户就可以在应用程序中使用该系统调用了。

(5)使用新的系统调用

在应用程序中使用新添加的系统调用mycall。同样为实验目的,我们写了一个简单的例子xtdy.c。

/* xtdy.c */
#include
_syscall1(int,mycall,int,ret)
main()
{
printf("%d \n",mycall(100));
}
编译该程序:
# cc -o xtdy xtdy.c
执行:
# xtdy
结果:
# 100
注意,由于使用了系统调用,编译和执行程序时,用户都应该是超级用户身份。

❼ 求教怎么学习linux内核驱动

1.首先要了解为什么要学习内核?下图已表明,如果要从事驱动开发或系统研究,就要学习内核。

2.内核的知识就像下面的绳结一样,一环扣一环,我们要解开它们,就必须要先找到线头也就是内核中的函数接口。初学阶段,我们一般不深入的研究内核代码,会使用内核的接口函数就不错了。

3.下面提供了如何学习这些内核函数的方法,就像解绳子一样

4.学习内核的四步法则,思维导图的设计尤为重要,这也是能否学习好内核的关键

5.语言基础也需要扎实,所以需要把C语言巩固巩固

❽ linux系统调用怎么和内核或底层驱动交互的

1、struct file_operations是一个把字符设备驱动的操作和设备号联系在一起的纽带,是一系列指针的集合,每个被打开的文件
都对应于一系列的操作,这就是file_operations,用来执行一系列的系统调用。
2、struct file代表一个打开的文件,在执行file_operation中的open操作时被创建,这里需要注意的是与用户空间inode指针的区
别,一个在内核,而file指针在用户空间,由c库来定义。
3、struct inode被内核用来代表一个文件,注意和struct file的区别,struct inode一个是代表文件,struct file一个是代表打开的文件
struct inode 包括很重要的两个成员:
dev_t i_rdev 设备文件的设备号
struct cdev *i_cdev 代表字符设备的数据结构,struct inode结构是用来在内核内部表示文件的。同一个文件可以被打开好多
次,所以可以对应很多struct file,但是只对应一个struct inode.

阅读全文

与系统调用提纲linux内核之旅相关的资料

热点内容
在vmos下载的文件路径在哪 浏览:771
有什么购物app是用微信支付的 浏览:99
数控编程中夹持什么意思 浏览:295
文件夹能容纳多少张截图 浏览:85
视频文件查找 浏览:786
如何进入java的编程界面 浏览:371
二级开发者还有哪些app 浏览:241
app充值请联系itunes 浏览:678
矢量app和cdr哪个好 浏览:85
系统文件坏了如何修复 浏览:20
键盘系统文件误删 浏览:738
白金英雄坛所有版本 浏览:842
ps文件转hsj 浏览:382
哪个网站电影 浏览:490
ps4游戏文件格式名称 浏览:290
caxa教程2007 浏览:832
新点是什么小说网站 浏览:753
魔兽世界冰封王座3版本转换器 浏览:418
苹果3dtouch软件 浏览:979
qq视频在哪个文件夹里面 浏览:740

友情链接