kernel笔记——库文件与系统调用
库文件
先从我们熟悉的c库入手,理解系统调用(system call)。c代码中调用printf函数,经历了以下调用过程:
最终输出的功能由内核中write调用完成,c库封装了系统调用。
对于以下hello world程序:
#include
int main()
{
printf("Hello world.\n");
return ;
}
我们可以使用ldd查看程序依赖的库文件:
linux # ldd hello
linux-vdso.so. => (0x00007fff89fe2000)
libc.so. => /lib64/libc.so. (0x00007fd142094000)
/lib64/ld-linux-x86-.so. (0x00007fd1423f2000)
输出结果中显示了hello程序依赖的动态库文件,其中linux-vdso.so.1指向进程虚拟内存地址,是一个虚拟的库文件,在每个程序的虚拟内存都存在,其将内核态的调用映射到用户地址空间中,使得调用开销更小。
有些时候,在我们编译程序时,会出现找不到某某lib的提示,又或者ldd查询到某库链接指示”not found”,这是因为ldd在/etc/ld.so.cache中不存在相应库文件的查找路径(使用strace跟踪ldd命令可以看到ld.so.cache文件被读取)。
要解决找不到某库的问题,我们可以将库文件路径加到用户的LIBRARY_PATH环境变量中,也可以添加到全局的/etc/ld.so.conf配置文件中,添加完后以root用户执行ldconfig,以更新/etc/ld.so.cache缓存文件。
使用rpm命令可以查到动态库属于哪个rpm包:
linux # rpm -qf /lib64/libc.so.
glibc-2.11.-0.17.
反过来,对某一rpm包,我们可以查其包含的内容:
linux # rpm -ql glibc-2.11.-0.17.
/etc/bindresvport.blacklist
/etc/default/nss
/etc/gai.conf
/etc/ld.so.cache
/etc/ld.so.conf
……
devel包中包含了c库函数的头文件,而普通包中不包含头文件,可以使用rpm查询对比开发包和普通包:
rpm -ql glibc-2.4-31.77.88.4
rpm -ql glibc-devel-2.4-31.77.88.4
系统调用
每一个系统调用对应一个系统调用号(system call number),使用系统调用的过程就是将系统调用号和参数传递给内核。
使用objdump,可以对库文件进行反汇编,以下对/lib64/libc.so.6进行反汇编,并查看getpid函数相应的部分汇编代码:
00000000000933e0 <__getpid>:
……
933fa:
933fb: c0 test %eax,%eax
933fd: f0 jne 933ef <__getpid+0xf>
933ff: b8 mov $0x27,%eax
: 0f syscall
: d2 test %edx,%edx
……
在以上输出中,mov指令将系统调用号0x27放入eax寄存器中,0x27作为syscall的参数,syscall完成调用getpid的工作。
系统调用与系统调用号对应关系在include/asm/unistd.h中定义,我们可以查到getpid相应的定义语句:
#define __NR_getpid 39
__SYSCALL(__NR_getpid, sys_getpid)
unistd.h定义了POSIX标准提供的系统调用,所有符合POSIX标准的Unix系统均提供该头文件。
我们可以直接传递系统调用号给syscall函数,完成系统调用,以下程序说明了如何使用syscall直接完成getpid系统调用:
#define _GNU_SOURCE
#include
#include
#include
#include
int main(int argc, char *argv[])
{
pid_t tid;
tid = syscall(SYS_gettid);
printf("%d\n", tid);
}
因而总结来说,使用系统调用的方式有两种:
- c库中封装了系统调用,通过c库间接调用
- 传递系统调用号,通过syscall直接调用
第2种方式存在的意义在于,当kernel提供了新的系统调用,而c库又没有更新时,可以使用syscall调用新的系统调用。
Reference: Chapter 5 - System Calls, Linux kernel development.3rd.Edition
kernel笔记——库文件与系统调用的更多相关文章
- linux库文件编写入门(笔记)
linux库文件的编写 作者: laomai地址: http://blog.csdn.net/laomai 本文主要参考了如下资料⑴hcj写的"Linux静态/动态链接库的创建和使用&quo ...
- makefile笔记10 - makefile 函数库文件
函数库文件也就是对 Object 文件(程序编译的中间文件)的打包文件.在 Unix 下,一般是由命令"ar"来完成打包工作. 一.函数库文件的成员 一个函数库文件由多个文件组成. ...
- python学习笔记(自定义库文件路径)
博主最近在弄接口自动化.主要是基于python自带的unittest框架.包括 Pubilc模块定义所有接口. Main模块根据业务需求重新封装接口便于测试. config文件导入测试业务的固定参数. ...
- 高级C/C++编译技术之读书笔记(四)之定位库文件
最近有幸阅读了<高级C/C++编译技术>深受启发,该书深入浅出地讲解了构建过程(编译.链接)中的各种细节,从多个角度展示了程序与库文件或代码的集成方法,提出了面向代码复用和系统集成的软件架 ...
- STM32嵌入式开发学习笔记(二):将功能封装为库文件
将所有的函数都堆在main.c文件里不是好的选择,庞大的代码文件会是你维护的障碍,明智的做法是,一种功能封装到一个库文件里. 库文件就是你代码开始部分写的#include<xxxx.h>里 ...
- 《linux内核设计与实现》读书笔记第五章——系统调用
第5章 系统调用 操作系统提供接口主要是为了保证系统稳定可靠,避免应用程序恣意妄行. 5.1 与内核通信 系统调用在用户空间进程和硬件设备之间添加了一个中间层. 该层主要作用有三个: 为用户空间提供了 ...
- Linux系统学习笔记:文件I/O
Linux支持C语言中的标准I/O函数,同时它还提供了一套SUS标准的I/O库函数.和标准I/O不同,UNIX的I/O函数是不带缓冲的,即每个读写都调用内核中的一个系统调用.本篇总结UNIX的I/O并 ...
- xv6学习笔记(3):中断处理和系统调用
xv6学习笔记(3):中断处理和系统调用 1. tvinit函数 这个函数位于main函数内 表明了就是设置idt表 void tvinit(void) { int i; for(i = 0; i & ...
- golang调用c++的dll库文件
最近使用golang调用c++的dll库文件,简单了解了一下,特作此笔记:一.DLL 的编制与具体的编程语言及编译器无关 dll分com的dll和动态dll,Com组件dll:不管是何种语言写的都可以 ...
随机推荐
- [Leetcode]538. Convert BST to Greater Tree
Given a Binary Search Tree (BST), convert it to a Greater Tree such that every key of the original B ...
- [Leetcode]237. Delete Node in a Linked List -David_Lin
Write a function to delete a node (except the tail) in a singly linked list, given only access to th ...
- shell之最常用的服务脚本
任务需求:以最简单的方式管理 /usr/local/php7/sbin/php-fpm -c /usr/local/php7/etc/php.ini 这条命令 包括启动停止重启 使用技术:shell脚 ...
- 痞子衡嵌入式:飞思卡尔Kinetis系列MCU启动那些事(3)- KBOOT配置(FOPT/BOOT Pin/BCA)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔Kinetis系列MCU的KBOOT配置. KBOOT是支持配置功能的,配置功能可分为两方面:一.芯片系统的启动配置:二.KBO ...
- python基础4--控制流
1.if语句 结构: if condition: do something elif other_condition: do something number = 60 guess = int(inp ...
- linux查看和修改PATH环境变量的方法
查看PATH:echo $PATH以添加mongodb server为列修改方法一:export PATH=/usr/local/mongodb/bin:$PATH//配置完后可以通过echo $PA ...
- 配置多个git账号的ssh密钥
博客改版,请直接访问新版文章:https://www.cnblogs.com/xiaoxi666/p/9975981.html 背景 我们在工作中会以 ssh 的方式配置公司的 git 账号,但是平时 ...
- SSM整合Netty5.0详细说明
阅读本文约“3.2分钟” 最近又有粉丝加Q群讨论netty整合SSM项目的方式等,我在这里抽了休息日的时候整理一下,一步一步的记录,注意的是,本案例仅实现了用netty整合SSM后与单片机等类TCP应 ...
- SpringDay01
Spring的控制反转 Spring的依赖注入 多种注入方式 多种属性的注入方式 <bean id="userDao" class="dao.UserDaoImpl ...
- xxxx-xx-xx的时间的加减
<!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="UTF-8& ...