![](https://img-blog.csdnimg.cn/20201014180756930.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
linux
文章平均质量分 60
alex_mist
coding....
展开
-
为树莓派4B编写platform驱动LED灯(采用DTS方式提供硬件信息)
最近学习了Linux platform driver子系统和dts的基本知识,写一个platform字符设备驱动来操纵GPIO控制LED灯,采用DTB文件来提供硬件信息,纯粹练手。修改DTS文件要修改DTS文件首先要确定自己使用的开发板所用DTB的版本,RPI 4B采用的是bcm2711-rpi-4-b.dts。下载一个在arch/arm/boot/dts/目录下有这个dts文件的linux内核源码,我下的是linux-5.10.31。通过查阅bcm2711的datasheet,找到和GPIO相关的物理原创 2021-05-22 14:55:23 · 857 阅读 · 1 评论 -
一个端口到底可以建立多少TCP连接?
一个端口到底可以建立多少TCP连接?这是一个很基础的问题,但是网上对于这个问题的解释千奇百怪。有人说,一个端口只能建立一个TCP连接,所以说无论服务还是客户端都最多只能建立65535个TCP连接。还有人说,服务端因为accept之后新建立的socket是重用listen的端口的,所以服务端最多可以建立65535×n个连接,而客户端connect建立的端口不可重用所以客户端只能65535。这里有两个误解:误解一:一个端口只能建立一个TCP连接。事实上Linux内核对TCP连接的识别是通过四元组来区分,原创 2021-05-14 16:21:24 · 16931 阅读 · 6 评论 -
ubuntu上mysql最彻底的删除方法
ubuntu上mysql最彻底的删除方法因为前段时间ubuntu给我自动更新,好像还在更新着我就给关机了还是怎么的,mysql就再也用不了了,而且安装也没办法安装。于是一鼓做气,把mysql彻底卸载了再重装!网上找到最好的方法:https://stackoverflow.com/questions/13276088/cant-start-mysql5-5-on-ubuntu-12-04-dpkg-dependency-problems我自己修改了下,亲测可行:sudo apt-get remove原创 2021-03-07 14:10:31 · 273 阅读 · 0 评论 -
C/C++中函数声明的作用
C/C++中函数声明和include头文件的作用参考:https://blog.csdn.net/qq_28648279/article/details/78463345一直想不明白,函数声明的作用。在include中我们只是把函数的声明放入代码了,调用函数的具体实现还是要看函数的定义,那么include函数声明到底有什么作用呢?按理说我只要能正确链接对应的函数定义就可以了呀?在参考的博客中看到这么一段话:”其实函数声明的作用是让编译器帮你检查你调用函数时有没有错误。比如参数的数量是否正确,如果调用函原创 2021-02-27 12:20:07 · 3469 阅读 · 0 评论 -
关于RCU-protected array indexes的探究
关于RCU-protected array indexes的探究在师兄的驱动代码中看到了几个和rcu index相关的代码在编译的时候报错,原因是现在的linux内核已经废除使用RCU-protected array indexes了。现在建议,用smp_load_acquire对rcu_dereference_index_check进行替换参加文章内容:Abolition of RCU-protected array indexesThe RCU API has long permitted RC原创 2021-02-25 17:30:52 · 104 阅读 · 0 评论 -
关于RCU-sched的研究
关于RCU-sched的研究对于synchronize_rcu原理的研究,在现在的源码中发现: * When synchronize_rcu() is invoked on one CPU while other CPUs * are within RCU read-side critical sections, then the * synchronize_rcu() is guaranteed to block until after all the other * CPUs exit the原创 2021-02-24 22:32:28 · 3841 阅读 · 0 评论 -
linux内核模块是如何调用的内核函数?
linux内核模块是如何调用的内核函数?在学习Linux设备驱动的过程一直有一个疑惑:我们在写用户空间程序的后自然是需要include用户空间的头文件,而头文件中声明函数的定义又需要编译成库或目标文件,链接到最终的可执行文件中去。但是在编写内核模块的时候,从哪里找的linux内核头文件呢?而linux内核头文件中对应函数的定义又放在哪里的呢?事实上我们想要编译内核模块首先就需要构建好内核源码树,或者直接使用本系统的内核头文件,我们一般都是直接使用本地的内核头文件的,放在:/usr/src/linux-原创 2021-02-08 17:14:32 · 1361 阅读 · 0 评论 -
Linux 在动态链接库中使用static静态函数会导致的问题
我们知道static静态函数相比于全局函数,会把范围限定在自己所在文件的范围,对其他的编译单元是不可见的!那么若在动态库中定义了static静态函数并完成库的编译,那么在主程序加载并试图调用这个static静态函数的时候会找不到它!因此需要在主程序中直接调用的函数在动态库中不要定义和声明为static类型!同样的问题也在stackoverflow有讨论:https://stackoverflow.com/questions/5526461/gcc-warning-function-used-but-n原创 2020-12-17 11:41:59 · 1153 阅读 · 2 评论 -
Linux 编译成功动态链接库但是运行时:error while loading shared libraries: liberr_handle.so: cannot open shared obje
今天遇到了一个问题,我写的动态链接库在编译链接的时候都没有问题:gcc test.c -o test -L ../lib/ -lerr_handle -g但是在运行时却报错:./test: error while loading shared libraries: liberr_handle.so: cannot open shared object file: No such file or directory明明我已经通过gcc的-L和-l参数指定了要去哪找动态链接库了,但是为什么在运行的时原创 2020-12-17 11:15:15 · 570 阅读 · 0 评论 -
KVM/QEMU安装配置方式
KVM/QEMU安装配置方式下载qemu:sudo apt install qemu上面分别是qemu可以模拟的各种架构,下载了Linux发行版的镜像之后,可以通过命令启动iso:创建虚拟机空间:qemu-img create -f qcow2 OS.img 20Gqemu-system-x86_64 -boot d -cdrom ubuntu-16.04-desktop-amd64.iso -hda OS.img -m 2048参数说明:qemu-system-x86_64命令是原创 2020-11-13 11:19:38 · 1018 阅读 · 0 评论 -
x86下KVM启动Jailhouse
x86下KVM启动Jailhouse首先按照官方文档需要关闭linux kernel的iommu:VT-d IOMMU usage (DMAR) has to be disabled in the Linux kernel, e.g. via the command line parameter:intel_iommu=off方法:修改/etc/default/grub(/etc下的是grub的配置文件,/boot下的真正启动时加载的grub文件),调整GRUB_CMDLINE_LINUX内容原创 2020-11-04 17:03:33 · 916 阅读 · 2 评论 -
为什么要分段?为什么要分页?
为什么要分段?为什么要分页?首先分页和分段都是为了更好的管理内存,是内存的管理方式。想象一下,假如没有分段和分页机制的情况是什么样的? 这种情况下相当于直接操作内存,那么程序员在写代码的时候要自己考虑并写死用哪些物理地址!而且程序的运行一定需要连续的地址来一次装入程序!上面的情况将引来三个问题:程序之间很容易相互影响,因为是直接操作内存的物理地址,那么程序B可能会出现修改覆盖程序A地址的情况!这种问题可以称为:没有有效隔离进程的地址空间!程序的地址难以把握,因为物理地址是写死的,假如程序写死操作原创 2020-09-21 22:05:56 · 4522 阅读 · 2 评论 -
fork()和vfork()各自的特性
fork()我们知道现代的fork()是已经应用了COW-Copy On Write的,父进程在fork()后创建的子进程先对父进程的数据段,堆段,栈段中的各页采用写时复制,令这些段的页表项指向父进程相同的物理内存页,并将这些页标记为只读!之后内核会通过写保护发现所有父进程或是子进程对页面的修改企图,并为将要修改的页面创建拷贝; 内核会将新的页面拷贝分配给遭到内核发现修改的进程; 之后父子进程可以分别修改各自的页拷贝而不再相互影响!例子:#include<stdio.h>#include原创 2020-09-11 09:30:09 · 79 阅读 · 0 评论 -
浅析Linux中PRI和NI的关系
Linux中:所有的优先级范围为0-139,一共140个优先级,数值越低优先级越高;优先级范围100-139称为静态优先级,这个范围里的进程属于非实时进程,调度方式是:SCHED_OTHER,也就是SCHED_OTHER,使用CFS算法调度(时间片)优先级范围0-99称为动态优先级,这个范围里的进程属于实时进程,调度方式有:SCHED_FIFO和SCHED_RR(默认);SCHED_FIFO:高优先级会抢占低优先级,高优先级运行期间,低优先级没法抢占,只能等到高优先级主动退出;对于同等优先级,先运原创 2020-06-22 15:29:28 · 1253 阅读 · 0 评论 -
Linux内核模块的自动加载及request_module系统调用
automatic kernel-module loadingLinux提供一种模块自动加载的机制,是通过request_module()系统调用实现的:当内核发现一个需要的module不在内核中时,会调用request_module去用户空间创建进程去加载这个缺失的module;For example, if an application opens a char device with a given major and minor number and no driver exists for原创 2020-06-03 15:38:24 · 2673 阅读 · 0 评论 -
原子操作,自旋锁,信号量,互斥体,顺序锁
参考自《Linux内核设计与实现》第10章中断上下文只能使用自旋锁,因为中断不能睡眠;一般信号量面向很底层的代码,互斥体和信号量首选互斥体,互斥体的count只能为1;读写锁适合于读多写少,并且代码中读写操作能明显分开的场景;在Linux中自旋锁是不能递归的(死锁);自旋锁,一定要在获取锁之前,首先禁止本地中断(禁止当前处理器的中断请求),原因是:比如:内核进程A获得了一个spinlock,但是没有禁止本地中断,这时发生中断,中断处理程序B打断了正在持有spinlock的进程A代码; 若是这个原创 2020-06-01 18:05:13 · 437 阅读 · 0 评论 -
fs_struct,file_struct,file,file_operations等的关联关系
先上一张图:task_struct不用多说,是Linux中的进程描述符;fs字段指向fs_struct结构体,是用来记录这个进程的工作目录pwd,和它的根目录root;显然目录信息是由dentry结构体保存的;在linux中,目录也是一种文件,因此dentry结构体会有指向inode结构体的指针字段d_inode;file字段指向files_struct结构体,这个结构体是用来记录该进程打开的所有文件的信息;每个打开的文件都会为它建立一个file(图中的files错误)结构体;files_struct原创 2020-05-27 10:01:57 · 688 阅读 · 0 评论 -
内核模块代码中的特性
标记了__init和__exit的函数,都是作用于模块的;__init:是载入模块时执行的操作__exit:是卸载模块时的操作printk是用来打印内核信息的函数,会将信息保存在系统日志,或是打印在控制台上;是否打印在控制台是取决于当前控制台日志级别,具体baidu已下是printk的日志级别#define KERN_EMERG"<0>"/*紧急事件消息,系统崩溃之前提示,表示系统不可用*/#define KERN_ALERT"<1>"/*报告消息,表示必须立即采取措施*原创 2020-05-26 15:12:50 · 390 阅读 · 0 评论 -
Linux中断异常好文
转载:http://blog.sina.com.cn/s/blog_6b94d5680101va6e.html前言总言之,有两大种代码的中断方式1:CPU的外部中断 导致CPU代码执行中断2:CPU本身在执行代码过程出现的 代码中断情况具体说,CPU的中断可以细分为下1:外部中断 >这种中断的发生完全是"异步"的,根本无法预测此类中断会在什么时候发生。因此,CPU(或者软件)对外...转载 2020-04-21 13:07:59 · 257 阅读 · 0 评论 -
C程序的存储空间布局
转自:https://www.linuxidc.com/Linux/2015-03/114888.htm当一个C程序执行之后,它会被加载到内存之中,它在内存中的布局如上图,分为这么几个部分,环境变量和命令行参数、栈、堆、数据段(初始化和未初始化的)、正文段,下面挨个来说明这几段分别代表了什么:环境变量和命令行参数:这些指的就是Unix系统上的环境变量(比如$PATH)和传给main函数的参数...转载 2020-04-15 11:55:35 · 221 阅读 · 0 评论 -
深入理解linux内核笔记-第三章进程process
进程是什么From the kernel’s point of view, the purpose of a process is to act as an entity of which system resources (CPU time, memory, etc) are allocated.进程其实就是一个系统资源分配的集合实体Although the parent and chil...原创 2020-04-14 19:21:02 · 769 阅读 · 0 评论 -
Unix C/C++编程-open(),read(),write(),sprintf(),lseek()
open()函数open函数返回的是int类型,成功返回的是int类型的文件描述符,失败返回-1文件路径是个char*指针打开方式比较常用的是O_RDONLY,O_WRONLY,O_TRUNCread()函数位于<unistd.h>中,原型:ssize_t read(int fd,void*buf,size_t count)fd为int类型的文件描述符,一般都是用一...原创 2020-04-09 19:57:20 · 494 阅读 · 0 评论 -
build,host,target三元组
build:执行代码编译的主机,正常的话就是你的主机系统。这个参数一般由config.guess来猜就可以。当然自己指定也可以。host:编译出来的二进制程序所执行的主机,因为绝大多数是如果本机编译,本机执行。所以这个值就等于build。只有交叉编译的时候(也就是本机编译,其他系统机器执行)才会build和host不同。用host指定运行主机。target:这个选项只有在建立交叉编译环境的时候...转载 2020-04-09 17:27:56 · 351 阅读 · 0 评论 -
系统调用和普通函数中参数的调用方式
普通函数的调用,参数的传递是通过压入栈的方式实现;汇编指令CALL之后,会入栈下一条指令的地址eip,要是要传递参数或是保护一些关键的上下文信息,需要顺序入栈相应的寄存器的值;再使用ebp来从栈中取出要用的参数,或是用pop来出栈参数系统调用int 0x80是去系统的中断向量表找到第0x80h位置,然后根据eax的值来确定是第几号系统调用功能,这里的参数是通过寄存器来传递的;为什么这里用寄...原创 2020-04-07 18:40:13 · 450 阅读 · 0 评论 -
Linux的 /etc/crontab
linux 系统则是由 cron (crond) 这个系统服务来控制的。Linux 系统上面原本就有非常多的计划性工作,因此这个系统服务是默认启动的。另 外, 由于使用者自己也可以设置计划任务,所以, Linux 系统也提供了使用者控制计划任务的命令 :crontab 命令。crond 是linux下用来周期性的执行某种任务或等待处理某些事件的一个守护进程,与windows下的计划任务类似,当安...转载 2020-04-02 13:13:25 · 346 阅读 · 0 评论