本文对内核中断进行概括以及讲述中断的具体实现方法在内核是怎么做的,会结合内核源码中的一些 .s 文件和 .c 文件来具体分析一下内核在中断中的实现方式。
wq = create_singlethread_workqueue("mydrv");
前面文章中介绍了一篇博客:Learning VPP: OSPF routing protocol,文章中介绍使用VPPsb的router插件,它实现了将控制报文推到Linux网络堆栈的逻辑,以及一个基于netlink的机制,它将Linux的路由表同步到VPP的FIB中。本文主要尝试vppsb router查询在最新vpp21.06版本编译。并配置简单的ping业务正常。
状态之间的转换 , 参考 【Linux 内核】进程管理 ( Linux 中进程的 CPU 资源调度 | 进程生命周期 | 创建状态 | 就绪状态 | 执行状态 | 阻塞状态 | 终止状态 | 进程生命周期之间的转换 ) 博客 ;
exit是c语言的库函数,他最终调用_exit。在此之前,先清洗标准输出的缓存,调用用atexit注册的函数等, 在c语言的main函数中调用return就等价于调用exit。
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014688145/article/details/50615579
大家好,我是程栩,一个专注于性能的大厂程序员,分享包括但不限于计算机体系结构、性能优化、云原生的知识。
系统编程课上遇到的一个问题:Linux下,如果一个 pthread_create 创建的线程没有被 pthread_join 回收,是否会和僵尸进程一样,产生“僵尸线程”?
http://blog.csdn.net/russell_tao/article/details/7090033
众所周知,C 语言相比于汇编语言拥有更为强大的灵活性和抽象能力,但相较于汇编语言,C 语言又缺乏了直接寻址、读写内存的强大能力。 同时,C 语言由于具备更强大的抽象能力,往往会造成生成的机器指令过多,因此,对于嵌入式编程等领域的 C 语言程序设计来说,有一个非常常用的优化方式,就是将 C 语言编译后反汇编为汇编语言,然后通过阅读并精简汇编语言,来实现代码优化的目的。 那么,既然 C 语言、C++ 可以被编译器反汇编为汇编语言,我们是否可以直接通过汇编语言调用 C 语言或者让 C 语言去调用汇编语言呢?答案当然是可以的。 本文,我们就来详细介绍,如何在 linux 环境下实现 C 语言与汇编语言的相互调用。
本文通过crash分析一个hang在tasklist_lock上的soft lockup,透过表象,来分析内核在有大量进程释放时的表现
前言 互联网公司一般都会运行着几千到几万的服务器。一般的监控会采用类似ganglia/falcon类似的工具,在本地启动一个agent,把数据统计上报到集中式的服务器中,用来监控和分析系统的问题。 另外,有atop这样的工具,可以运行在服务器上,在本地写下record文件,atop命令本身也可以分析record文件,其中保存的数据的粒度更加细致,可以精确到线程级别,还有IPC,主频等等。 经验来看,atop每天生成的record文件大约500M左右,保存最近的一段时间,似乎也不是问题。用集中式的监控,配合上atop,对于问题分析来说,会有一些帮助。 分析 1,atop的改进 atop的代码量本身并不大,官方的代码在: https://github.com/Atoptool/atop.git 在使用atop的过程中,遇到了一些问题,作者也做了相应的修改: https://github.com/bytedance/atop 在bytedance-features分支上。作者把patch发送给maintainer,但是maintainer一直没有回复。在这里,列举一下改动的内容,如下。 2,smaps的优化 尝试使用smaps_rollup代替smaps,用来提高atop收集进程的PSS内存使用的效率。这个patch会在4.14上有所提升。一般情况下,建议在atop收集的时候不要加上-R选项。因为在atop读/proc/PID/smaps的时候,会walk整个PID进程的页表,期间会lock住内存页表的锁。如果在这期间PID进程发生了page fault,也需要lock,就会造成锁的进程。影响PID进程的性能。 3,数据破损问题 atop使用裸数据的方式保存record文件,其中包括三部分:raw record,就是头信息; scompbuf,是系统状态信息的数据; pcompbuf,是task级的状态信息数据,大小和task数量有关系。为了减小record文件的大小,对于 scompbuf和pcompbuf还采用了压缩。所以,数据必须完整的 rr,scompbuf,pcompbuf顺序写下去的,否则atop无法识别数据。 good case : ... rr,scompbuf,pcompbuf ... rr,scompbuf,pcompbuf ... bad case : ... rr,scompbuf[missing] ... rr,scompbuf,pcompbuf … 例如上面的例子,在写完rr,scompbuf之后,atop发生了crash,再重新启动,就会丢失后面的 pcompbuf,造成了整个record文件的不可用。 在patch中,作者使用writev进行写入数据,要么都写入成功,要么都写入不成功,用来防止这种case发生。 4,IPC造成的虚拟机性能抖动 IPC,instructions per cycle。可以用来衡量CPU运行的效率。通常是通过perf采集的数据。 提到perf,就要说明一下它的工作原理:intel的CPU上集成了PMU,用来采集硬件的信息。可以收集的硬件信息很多,可以通过perf list | grep Hardware来看。但是硬件的寄存器有数量限制,所以需要通过wrmsr指令告诉CPU收集哪些具体的事件,再通过rdpmc指令来读取对应的数据。 在虚拟化场景下,在虚拟机中使用PMU又复杂了一下,在虚拟机中执行wrmsr和rdpmc的时候,都需要虚拟机从none-root模式退出,影响了虚拟机的性能。 在patch中,作者让atop支持perfevents的配置,支持三种模式:enable模式,启用perf收集IPC。disable模式,禁用perf收集IPC。auto模式,在启动的时候,atop自动检查是否在虚拟机中运行,如果在虚拟机中,禁用;在物理级中,启用。默认是auto模式。 5,减小record文件 如果是大规格的服务器,40CPU,甚至到96CPU,通常运行大量的docker,里面运行了很多的task。其中很多task占用资源很少,但是依然会占用atop的record文件。 在patch中,支持了配置参数recordcputop & recordmemtop。用来配置收集cpu和内存的topN。其他的task可以忽略。作者测试线上的服务器36CPU, about 500 processes的场景,大约节省了40%的磁盘空间。 6,加速读record 一般在ganglia上看到系统抖动,例如下午三点十分,在对应的服务器上执行: atop -r / var/log/atop/atop_xxxx -b 15:10 如前文所述,因为rawrecord的原因,则会从头读到尾,直到匹配到对应的时间。对于log盘的使用,尤其是虚拟化场景,会限制IOPS。这
进程是Unix操作系统最基本的抽象之一。一个进程就是处于执行期的程序(目标码存放在某种存储介质上)。但进程并不仅仅局限于一段可执行程序代码(Unix称其为代码段(textsection))。通常进程还要包含其他资源,像用来存放全局变量的数据段(text section)、打开的文件、挂起的信号等,当然还包含地址空间及一个 或几个执行线程(threads of execution)。
这个教程试着向读者展示最基本的栈溢出攻击和现代Linux发行版中针对这种攻击的防御机制。为此我选择了最新版本的Ubuntu系统(12.10),因为它默认集成了几个安全防御机制,而且它也是一个非常流行的发行版。安装和使用都很方便。我们选择的系统是X86_64的。读者将会了解到栈溢出是怎样在那些默认没有安全防御机制的老系统上面成功的溢出的。而且还会解释在最新版本的Ubuntu上这些保护措施是如何工作的。我还会使用一个小例子来说明如果不阻止一个栈上面的数据结构被溢出那么程序的执行路径就会失去控制 。
对于一个操作系统来说,提供运行程序的能力是其本质,而在 Linux 中,轻量、相应快速的进程管理也是其优良特性之一。我会分两篇文章介绍 Linux 进程。这是第一篇,重点在于 Linux 进程的描述和生命周期,下一篇将介绍 Linux 下的进程调度。
关于调度时机,网上的文章也五花八门,之前在内核抢占文章已经做了详细讲解,而在本文我们从源码注释中给出依据(再次强调一下:本文的调度时机关注的是何时调用主调度器,不是设置重新调度标志的时机,之前讲解中我们知道他们都可以称为调度时机)。
http://blog.csdn.net/jnu_simba/article/details/25158661
一. linux内核简介 1. linux简介 1.1 unix的特点 unix很简洁,仅提供几百个系统调用,并有非常明确的设计目的 unix所有东西都当作文件对待,这种抽象使对数据和设备都通过一套相同的系统调用接口进行 内核用C语言编写,移植能力很强 进程创建迅速,独特的fork调用 提供了简洁但是稳定的进程间通讯原语 1.2 unix和linux linux克隆unix,但不是unix linux借鉴了unix很多的设计,并且实现了 unix的api linux没有直接使用unix的源代码,但完整表达了
我们用下面的C代码来研究函数调用的过程。 int bar(int c, int d) { int e = c + d; return e; } int foo(int a, int
注意: ①printf函数在stdio.h文件里,需要包含头文件stdio.h ②exit函数在stdlib.h文件里,需要包含头文件stdlib.h文件 ③‘\n'除了换行的作用外,还有刷新缓冲区的功能 ④关于main函数的写法,读者可能见过很多种,包括 void main(void) void main() int main() int main(void) int main(int agrc, char** argv)// char* agrv[] 编者在这里建议读者使用后面两种写法,严格上讲这两种才是标准的。
通过使用本地文件、Open Source U-Boot/Linux编译,既能适应部分开发人员的工作习惯,也能提高U-Boot/Linux的编译速度。
静态加载, 把驱动模块编进内核, 在内核启动时加载 动态加载, 把驱动模块编为ko, 在内核启动后,需要用时加载
这篇文章介绍在Linux下如何编写FT5X06系列芯片驱动,完成触摸屏的驱动开发, FT5X06是一个系列,当前使用的具体型号是FT5206,它是一个电容屏的触摸芯片,内置了8位的单片机(8051内核),完成了坐标换算等很多处理,在通过IIC,SPI方式传递给外部单片机。
最近需要开发一些内核模块,进行探究linux内核的一些特征,现在把一些遇到的比较好的文章和知识点,进行简要记录和备忘;
Linux给应用程序提供了丰富的api,但是有时候我们需要跟硬件交互,访问一些特权级信息,所以可以使用编写内核模块这种方式。 另外Linux是宏内核结构,效率非常高,没有微内核那样各个模块之间的通讯损耗,但是又不能方便的对内核进行改动,可扩展性和可维护性比较差,内核模块提供了一种动态加载代码的方式,弥补了宏内核的不足。
PCF8591是一个IIC总线接口的ADC/DAC转换芯片,功能比较强大,这篇文章就介绍在Linux系统里如何编写一个PCF8591的驱动,完成ADC数据采集,DAC数据输出。
在我离职之前,工作内容几乎不涉及到驱动方面的知识。我所要做的内容就是把客户对设备的请求拆分成一个一个的接口,调用驱动的设置进行配置就可以了。当然,至于驱动下面是怎么实现那就要根据具体情况而定了。比如说,有的驱动是芯片厂商直接写好的,假设芯片厂商提供了对应平台的sdk函数,那么驱动的工作就是对这些sdk函数进行封装就可以了,另外一种就是自己编写具体平台的驱动接口了。比如说,现在你需要编写串口、i2c、i2s、FLASH、网卡、LCD、触摸屏、USB驱动了。这个时候,你手里面除了一堆芯片手册,啥也没有。能不能调试成功,就看你自己的了。当然,一般情况下,在特定的平台上会有很多同类型的demo代码,你可以依葫芦画瓢修改一下,除了中断、地址、读写等部分注意一下,大部分的逻辑其实差异不大。至于修改的速度快不快就看你自己的了。
几年前,我写过两篇关于用C#开发Linux守护进程的技术文章,分别是《.NET跨平台实践:用C#开发Linux守护进程》和《.NET跨平台实践:再谈用C#开发Linux守护进程 — 完整篇》。
文章目录 Linux——进程管理篇(详解fork和exec) 🚗如何在Linux编写与运行代码 编写 编译 运行 🚗进程管理 fork system exec 🚗总结 Linux——进程管理篇(详解fork和exec) 🚀🚀这篇文章,主要的目的就是帮助同学们完成操作系统的实验,因为考虑到很多同学第一次接触Linux,相当不习惯命令行的操作方式,所以我会详细来介绍,相信只要跟着步骤一步一步来,就一定能完成我们的实验,好了,我们接下来就来介绍吧! ---- 🚗如何在Linux编写与运行代码 🚀🚀做实验,首
本章介绍所有的关于模块和内核编程的关键概念,通过一个 hello world 模块来认识驱动加载的流程及相关细节。
距离上一次更新有一段时间了,主要是最近更忙一些,一般来说,有时间我会尽量更新,如果比较忙的话就更新慢一些。
进程是操作系统中的一个重要概念,它是一个程序的一次执行过程,程序是进程的一种静态描述,系统中运行的每一个程序都是在它的进程中运行的。
安全研究人员近日曝出一个名为幽灵(GHOST)的严重安全漏洞,这个漏洞可以允许攻击者远程获取操作系统的最高控制权限,影响市面上大量Linux操作系统及其发行版。该漏洞CVE编号为CVE-2015-0235。 什么是glibc glibc是GNU发布的libc库,即c运行库。glibc是linux系统中最底层的api,几乎其它任何运行库都会依赖于glibc。glibc除了封装linux操作系统所提供的系统服务外,它本身也提供了许多其它一些必要功能服务的实现。glibc囊括了几乎所有的UNIX通行的标准。 漏
字符设备驱动中的 read接口的使用,简单实例 驱动部分代码
Tiny4412开发是友善之臂推出的Android、Linux学习开发板,CPU采用三星的EXYNOS4412,32位芯片,属于Cortex-A系列,主频是1.5GHZ,可以运行ubuntu、Android5.0、纯Linux等操作系统。
使用命令建立一个设备 s 驱动代码 #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/fs.h> #include <linux/device.h> #include <linux/cdev.h> #include <linux/major.h> static ssize_t flash_env_dev_open(struct inode *i
目录 前言 模块与系统调用 用模块打印Hello, world! 用模块添加自定义系统调用 top指令 关闭Linux图形界面 重编内核添加系统调用 解压系统源代码 撰写自定义系统调用 编译内核 测试新内核 最后 ---------- 前言 要自定义系统调用, 常规的两个方法是模块和重编内核, 一起来看看吧. 更新: 在64位ubuntu12.04.5上也成功运行. 解决了14.04, 16.04, 18.04上的问题. ---------- 模块与系统调用 用模块打印Hello, world! 首先看下系
惠伟:linux time和kvm time虚拟化综述zhuanlan.zhihu.com
上节 从一个简单的汇编程序学习汇编程序的结构以及编译链接的过程中,打印hello world的汇编程序的详细解释为:
很早之前就有网友建议写一篇关于Linux驱动的文章。之所以拖到现在才写,原因之一是我之前没有在工作中遇到需要自己手动去写驱动的需求,主要是现在Linux内核驱动的支持已经比较完善了,另外一个原因是自己水平实在有限,不敢写驱动这个话题,Linux驱动里涉及到的东西太多了,很多年前专门买过驱动相关的书籍,厚厚的,看的云里雾里。借此机会,在这里给大家做个非常非常入门级的介绍,希望对大家有所帮助。
使用字符设备里的write 驱动代码 #include <linux/module.h> #include <linux/slab.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/fs.h> #include <linux/device.h> #include <linux/cdev.h> #include <linux/major.h> #include <asm/uaccess.h> static ssi
我们就继续以此为基础,用保姆级的粒度一步一步操作,来讨论一下字符设备驱动程序的编写方法。
前言 要自定义系统调用, 常规的两个方法是模块和重编内核, 一起来看看吧. ---- 模块与系统调用 用模块打印Hello, world! 首先看下系统版本和内核版本. 我用的是32位的ubu
2015年1月28日互联网上爆出Linux glibc幽灵漏洞(glibc gethostbyname buffer overflow,http://seclists.org/oss-sec/2015/q1/274),也有人将其称之为“20150127GHOST gethostbyname() heap overflow in glibc”,在CVE上的漏洞编号是CVE-2015-0235。***者可利用此漏洞实施远程***,并完全控制目标系统。
在这篇中遗留了几个问题,先尝试回答一下,不一定准确,代码太多,看不过来,全靠猜测,代码的历史很长,都是智慧的结晶,一时半会消化不了很正常。
前言 之前的文章里面说了简单的.ko文件编译. 这里继续深入下去. 当然, 还是从驱动的Hello, world!开始. ---- 驱动模块里的Hello, world! 首先是源码部分, 这里由于是内核, 所以c库的函数就不能用了, 比如printf这样的, 要用printk替代, 这里的k就是指kernel. 然后__init和__exit意味着只有初始化和卸载才会执行函数, 也就是都只执行一次. module_init和module_exit理解为注册函数就行了. #include<l
为什么会写这样一篇“无效水文”,我想是由于我的这样一种强迫症,对于任何的学习,在不理解原理,无法把他与我的已知知识架构产生联系的时候,我会本能地拒绝这种知识,所以由于这种偏执,很多情况下拖慢了自己的进度,因为很多时候无法有效收集到有用的资料,软件实训的时候,老师只会丢给一个配置文件,然后在此基础上做一些修改开发,可以除了可以勉强做一个垃圾出来,没有任何意义。就连再去做一个垃圾的能力都没有。这种情况直到毕业我才感觉无法再继续这样的生活了,于是开始大量学习,阅读专业书籍。这次就想对这些原本困扰我的东西进行一次小的抛砖引玉式的总结,当然也是把别人已经写过的一些文章综合一下,让入门的人对此好奇的人产生初步印象。 总之,人生没有白走的路。五年之前你正在梦想你今天的生活。 还有,当我们在经历冬季的时候,新西兰正被春风吹拂。所以做自己认为对的事情吧。
大家好,我是道哥。今天给大家分享一些笔记本里的一些存货: Linux 系统中的驱动和中断相关。
EXPORT_SYMBOL只出现在2.6内核中,在2.4内核默认的非static 函数和变量都会自动导入到kernel 空间的, 都不用EXPORT_SYMBOL() 做标记的。 2.6就必须用EXPORT_SYMBOL() 来导出来(因为2.6默认不到处所有的符号)。
开发过单片机的小伙伴可以看一下我之前的一篇文章从单片机开发到linux内核驱动,以浅显易懂的方式带你敲开Linux驱动开发的大门。
领取专属 10元无门槛券
手把手带您无忧上云