Linux内核编程03期:系统调用

高端的程序员往往采用最朴素的编程方式。

能不能复用别人的代码,避免重复造轮子,是衡量程序员工作效率、是否能按时下班的关键。我们编写一个add()函数,只要封装得好,就可以给很多人使用,这样就可以减少他人重复劳动,避免重复造轮子。

// add.c 
int add(int a, int b)
{
   return a + b;
}

//add.h
int add(int a, int b);

其他的开发者,需要调用add()时,只要在自己的程序中使用#include包含对应的头文件add.h,就可以直接调用add()函数,不用自己再写一遍了。

我们将很多类似的函数打包,归档成一个库,引出对应的头文件声明,就可以供很多人调用和使用了。

# gcc -c add.c -o add.o
# gcc -c sub.c -o sub.o
# ar rcs libmath.a add.o sub.o

将这些库,放到操作系统的指定官方目录(如/lib、/usr/lib),随操作系统一起发布,对应函数的声明头文件(add.h sub.h),也放在操作系统的指定目录(如/usr/include)。程序开发者就可以在他们的程序中直接使用这些函数了:

#include <add.h>
int main(void)
{
    int sum = 0;
    sum = add(3, 4);

    return 0;
}

然后我们在编译程序时指定需要的链接库就可以了:

# gcc main.c  -L. -lmath

如果一些库在编译参数设置时是默认链接的,如C标准库,就不需要显式指定要链接的库了,直接编译程序就可以了。

如果从软件复用的角度看操作系统,操作系统其实也可看做一个库:操作系统对计算机的资源做了各种封装:任务创建、内存管理、文件系统、网络通信,并引出一系列接口给用户使用,避免用户重复造轮子。以uc/os为例,我们需要创建一个多任务程序,就可以直接将uc/os源码直接导入到我们的项目中,然后直接调用uc/os提供的接口即可:

#include "ucos_ii.h"
int main(void)
{
   OSInit();      //初始化OS
   OSTaskCreate();//创建一个任务
   OSStart();     //开启任务调度
}

到了Linux时代,操作系统发布商、应用程序开发者开始分离,由不同的团队和公司完成开发。用户可以自己下载自己喜欢的软件安装到电脑上,成千上万的开发者,成千上万的软件,对安全构成了很大的挑战。为了安全起见,Linux使用了权限管理:操作系统和应用程序分别运行在内核态和用户态,具有不同的权限:应用程序运行在普通权限下,不能访问硬件,而操作系统则运行在特权模式下,可以直接操作系统,读写寄存器,切换CPU的工作模式...

有了权限管理,Linux内核实现的各种函数接口,应用程序就无法像uc/os那样直接调用了。但Linux内核向应用程序提供了系统调用的访问接口:软中断指令,如X86的处理器的INT指令,ARM处理器的SWI/SVC指令,应用程序可以通过软中断,陷入Linux内核,去执行内核实现的各种的接口函数。

#include <sys/types.h>
#include <unistd.h>

int main()
{
   pid_t pid;
   
   pid = fork();
   if(pid < 0)
       printf("fork failed!\n");
   else if(pid == 0)
       printf("child process\n"); 
   else
       printf("parent process\n");
   return 0;
}

其中的fork只是一个系统调用接口函数,真正的实现是在内核中的sys_fork()中实现的。C标准库glibc再对这些接口进行封装,就成了我们大家熟悉的read、write、open、close等系统调用函数了,用户就可以像调用普通函数一样,通过这些接口,去调用Linux内核中实现的各种系统调用函数了。

想要了解系统调用更多细节:比如在X86、ARM架构上的不同实现,CPU、操作系统和glibc三者是如何配合的,包括最新版本内核使用的快速系统调用、虚拟系统调用、VDSO是怎么回事,请关注 《Linux内核编程》第03期:系统调用。

本期课程主要内容:

  1. 系统调用的基本概念
  2. 软中断:系统调用的入口(ARM)
  3. 软中断:系统调用的入口(X86)
  4. 系统调用的接口封装:glibc
  5. 系统调用的接口封装:syscall
  6. 系统调用流程分析
  7. 添加一个系统调用
  8. 系统调用的开销
  9. 快速系统调用
  10. 系统系统调用:vsyscall
  11. 虚拟动态共享对象:VDSO
  12. 从系统调用角度看文件的读写流程

本期课程共12个课时,视频总大小1.56GB,总时长3小时9分钟。

Linux内核一直是学习的难点:将近3000万行代码,5万多个源文件,代码庞大繁杂、代码很难看懂。《Linux内核编程》将突破以往传统的学习方式,采取更有效和科学的学习方法,多角度地对内核进行多层次分析,不局限于形式,不拘泥细节,目的只有一个:更轻松、更高效地去理解内核、学习内核。为了更好地让学员掌握内核编程技能,更好地理解内核,本课程将采用并不局限于以下学习方法进行课程的录制:降维分析,化简为繁,将复杂的系统简单化用软件工程的方法分析内核:软件分层、模块化分解、框架迭代多角度立体分析Linux内核,目的只有一个:更好地理解内核利用Linux内核中的面向对象编程思想去分析复杂的子系统、子系统交互利用多任务编程的思想去分析Linux内核本套课程预计分为20个左右的小模块,每个模块一个专题,每个专题会陆续发布。拟录制的模块包括但不限于:模块机制、内核裁剪与配置、内核编译与启动、系统调用、中断、文件系统、调度、内存管理、内核同步、设备模型、字符驱动、块驱动、定时器、input、platform设备驱动、device tree、proc、sysfs、I/O...  本课程是《Linux内核编程》的入门篇,主要给大家介绍一下Linux内核开发、Linux驱动开发的就业行情、行业生态、需要掌握哪些技能、Linux内核的学习方法、如何搭建Linux内核的学习开发环境。 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宅学部落-王利涛

just for test

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值