
linux内核
小小城御园
生命在于折腾,知识在于积累
展开
-
linux添加一个系统调用(syscall)
添加系统调用函数头文件在include/linux/syscalls.h文件中的#endif前添加自己的系统调用函数声明,内容如下:asmlinkage long sys_test(void);添加系统调用实现源码随便找一个文件,我们在这个文件中添加系统调用的源码SYSCALL_DEFINE0(test) ,内容如下:SYSCALL_DEFINE0(test){ ...原创 2020-02-12 22:35:11 · 4792 阅读 · 1 评论 -
error:a label can only be part of a statement and a declaration is not a statement解决办法
原因是由于我在case之后进行变量的声明而导致的错误对此问题的分析: 由于switch的几个case语句在同一个作用域(因为case 语句只是标签,它们共属于一个swtich语句块),所以如果在某个case下面声明变量的话,对象的作用域是在俩个花括号之间 也就是整个switch语句,其他的case语句也能看到,这样的话就可能导致错误。我们可以通过在case后面的语...原创 2019-04-24 21:52:40 · 32236 阅读 · 6 评论 -
点阵字库HZK32的使用方法和显示
汉字库种类非常多,但是都是按照顺序排列的。前一个字节为该汉字的区号,后一个字节为该字的位号。每一个区记录94个汉字,位号则为该字在该区中的位置。因此,汉字在汉字库中的具体位置计算公式为:(94*(区号-1)+位号-1)*字节数(一个汉字字模占用的字节数)。以32*32点阵字库为例,计算公式则为:(94*(区号-1)+(位号-1))*32*32/8。32*32字模为长和宽都是32位的数...原创 2019-05-18 23:43:18 · 5170 阅读 · 0 评论 -
linux相关代码下载链接
1、linux源码下载地址https://mirrors.edge.kernel.org/pub/linux/kernel/2、uboot源码下载http://ftp.denx.de/pub/u-boot/3、busybox下载地址https://busybox.net/downloads/4、glibc下载地址http://ftp.gnu.org/gnu/gl...原创 2019-05-24 22:58:14 · 397 阅读 · 0 评论 -
命令行处理函数getopt的使用方法
日常开发中,会经常对命令行参数进行处理,当参数比较少的时候,可以手动处理,但是当参数过多的时候就要使用getopt来处理了。int getopt(int argc, char * const argv[], const char *optstring);extern char *optarg;extern int optind, opterr, op...原创 2019-05-12 21:09:45 · 456 阅读 · 0 评论 -
命令行处理函数getopt_long的使用方法
getopt_long函数,getopt_long函数具有getopt函数的所有功能,并且还可以指定“长参数”,getopt_long比getopt多了两个参数: int getopt_long(int argc, char * const argv[], const char *optstring, ...原创 2019-05-12 22:00:40 · 375 阅读 · 0 评论 -
库函数argz_add、argz_add_sep使用方法
一、argz_add函数函数原型:error_t argz_add(char ** argz ,size_t * argz_len ,const char * str); 头文件:#include <argz.h> 返回值:0:成功ENOMEM:空间不足 功能:在数组* argz的末尾添加字符串str,并更新* argz和* argz_len: argz...原创 2019-05-26 14:40:02 · 621 阅读 · 0 评论 -
库函数argz_append、argz_count使用方法
一、argz_append函数函数原型:error_t argz_append(char ** argz,size_t * argz_len,const char * buf,size_t buf_len); 头文件:#include <argz.h> 返回值:0:成功ENOMEM:空间不足 功能:在(* argz,* argz_len)之后追加argz向量(buf,b...原创 2019-05-26 15:14:37 · 1136 阅读 · 0 评论 -
__define_initcall(level,fn)和do_initcalls()的妙用
__define_initcall(level,fn)将一系列初始化函数的起始地址值按照一定的顺序放在一个section中。在内核初始化阶段,do_initcalls()将按顺序从section中以函数指针的形式取出这些函数的起始地址,来依次完成相应的初始化。由于内核某些部分的初始化需要依赖于其他某些部分的初始化的完成,因此这个顺序排列常常非常重要。一、分析__define_i...转载 2019-06-02 15:08:18 · 679 阅读 · 0 评论 -
module_init与module_exit的分析
在编写驱动模块的时候有两个函数经常被使用也必须被使用,分别是module_init和module_exit,这两个函数分别在加载和卸载驱动时被调用,即调用insmod和rmmod命令的时候,但是insmod和rmmod不能识别这两个函数,它只能识别init_module和cleanup_module,其实init_module和cleanup_module相当于是module_in...原创 2019-06-02 16:04:47 · 6108 阅读 · 0 评论 -
Linux SPI总线和设备驱动架构之一:系统概述
SPI是"Serial Peripheral Interface" 的缩写,是一种四线制的同步串行通信接口,用来连接微控制器、传感器、存储设备,SPI设备分为主设备和从设备两种,用于通信和控制的四根线分别是:CS 片选信号SCK 时钟信号MISO...转载 2019-06-02 20:12:17 · 188 阅读 · 0 评论 -
bad variable nameame错误解决
脚本内容如下:#!/bin/bashread nameecho $name运行结果如下:原因为:shell脚本的编写是在windows进行的,是在notpad++中实现的解决办法为:修改为vim中编写,直接将脚本内容在vim编辑器中复制到shell文件中在运行就不会出错了 ...原创 2019-01-19 23:19:27 · 6611 阅读 · 0 评论 -
可变参数的应用-printf函数的实现
可变参数最典型的应用就是打印函数的格式化输出,下面就以一个简单的程序讲解printf函数的实现实际上是依赖于字符的打印,所有打印的实现都离不开字符的打印,下面就以字符的打印实现几个格式化输出的函数,其中主要用到的可变参数。字符函数的打印就使用: printf("%c",char);下面就使用字符的打印实现格式化输出函数#include <stdio.h>...原创 2019-01-08 23:14:44 · 388 阅读 · 0 评论 -
中断底半部机制之工作队列详解
工作队列的使用方法和tasklet 非常相似,下面的代码用于定义一个工作队列和一个底半部执行函数。struct work_struct my_wq; /*定义一个工作队列*/void my_wq_func(unsigned long); /*定义一个处理函数*/通过INIT_WORK()可以初始化这个工作队列并将工作队列与处理函数绑定,这两种方式最后产生的效果是一样的,为了方便建议使...原创 2018-11-19 22:53:13 · 257 阅读 · 0 评论 -
中断下半部的妙用
中断下半部中断处理程序是内核中很重要的一部分,但是由于本身存在着一些限制,所以他只能完成整个中断处理程序中的上半部分。具体局限如下:中断处理程序是以异步方式运行,并且他有可能会打断其他重要的代码(甚至有可能是其他的中断程序)的执行,因此为了避免被打断的代码停止时间过长。中断处理程序要执行的越快越好 如果当前有一个中断处理程序正在执行,在最好的情况下,在最好的情况下(IRQF_DISA...原创 2018-11-20 23:02:56 · 181 阅读 · 0 评论 -
中断底半部机制之tasklet详解
tasklet 的使用较简单,我们只需要定义tasklet 及其处理函数并将两者关联,例如:void my_tasklet_func(unsigned long); /*定义一个处理函数*/DECLARE_TASKLET(my_tasklet, my_tasklet_func, data);/*定义一个tasklet 结构my_tasklet,与my_tasklet_func(data)...原创 2018-11-19 22:41:29 · 656 阅读 · 0 评论 -
自旋锁使用详解
自旋锁1、概念 它是为实现保护共享资源而提出一种锁机制。其实,自旋锁与互斥锁比较类似,它们都是为了解决对某项资源的互斥使用。无论是互斥锁,还是自旋锁,在任何时刻,最多只能有一个保持者,也就说,在任何时刻最多只能有一个执行单元获得锁。但是两者在调度机制上略有不同。对于互斥锁,如果资源已经被占用,资源申请者只能进入睡眠状态。但是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元...原创 2018-11-12 23:10:17 · 2528 阅读 · 0 评论 -
原子操作详解
原子操作原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会被其他进程打断。它是其他内核同步方法的基石。编写代码时能使用原子操作的,就尽量不要用加锁机制,因为原子操作给系统带来的开销小。 一、原子整数操作 1、类型的定义 针对整数的原子操作只能对atomic_t类型的数据进行处理typedef struct { vol...原创 2018-11-12 22:35:42 · 1156 阅读 · 1 评论 -
linux内核态文件操作函数
1.打开文件struct file *filp_open(const char *filename, int flags, int mode)filename:要打开的文件的路径 例:“/dev/ttyGS0”flags:打开文件的方式O_CREAT 创建O_RDWR 读写 O_RDONLY 只读O_WRONLY 只写O_TRUNC 清空...原创 2018-12-18 23:03:48 · 581 阅读 · 0 评论 -
c和指针读书笔记三之转义字符
想在一些上下文中使用某一些特定字符的时候,比如说“”双引号,此时我们可以使用转义字符\,\?表示的是?,\”可以表示”,同事也可以防止三字母词。以下几种情况属于例外情况:\a 警告字符\b 退格键\f 进制字符\n 换行符\r 回车符\t 水平制表符\v 垂直制表符\ddd 表示1~3位八进制数所代表的字符 \ddd 表示1~3位八进制数所代...原创 2019-01-03 23:37:35 · 268 阅读 · 0 评论 -
为什么char类型的范围是 -128~+127
在C语言中, signed char 类型的范围为-128~127,每本教科书上也这么写,但是没有哪一本书上(包括老师)也不会给你为什么是-128~127,这个问题貌似看起来也很简单容易, 以至于不用去思考为什么,不是有一个整型范围的公式吗: -2^(n-1)~2^(n-1)-1 n为整型的内存占用位数,所以int类型32位 那么就是 -(2^31)~2^31 -1 即 -21474...转载 2019-01-04 22:22:11 · 249 阅读 · 0 评论 -
c和指针读书笔记一之编译
Gcc的编译流程分为了四个步骤: 1.预处理,生成预编译文件(.文件):gcc –E hello.c –o hello.i 2.编译,生成汇编代码(.s文件):gcc –S hello.i –o hello.s 3.汇编,生成目标文件(.o文件):gcc –c hello.s –o hello.o 4.链接,生成可执行文件: gcc ...原创 2019-01-02 22:03:59 · 159 阅读 · 0 评论 -
c和指针读书笔记二之注释
C语言中的注释以/*开始以*/结束,中间可以包含出*/之外的全部字符,注释不可以嵌套。注释会在预处理阶段被替换掉,取而代之的是一个空格,因此只要是可以在任何空格出现的位置出现。以下语句是等价的:y=x+1;y = x + 1;y =x+1;下面一组前三个语句是一致的:IntX;Int x;Int /*111111*/ x;Intx;...原创 2019-01-02 23:17:54 · 161 阅读 · 0 评论 -
可变参数列表
可变参数列表是通过宏来实现的,最典型的应用是printf函数的实现,这些宏定义于stdarg.h头文件,他是标准库的一部分。这个头文件生命了一个类型vs_list和三个宏:va_start、va_arg、va_end。我们可以声明一个va_List的变量,与这几个宏配合使用。例:编写一个函数计算几个数的平均值,函数的第一个参数为要计算的数的个数#include <stdio.h&g...原创 2019-01-08 22:53:18 · 2018 阅读 · 0 评论 -
等待队列详解
1.定义“等待队列头”。wait_queue_head_t my_queue;2.初始化“等待队列头”。init_waitqueue_head(&my_queue);而下面的DECLARE_WAIT_QUEUE_HEAD()宏可以作为定义并初始化等待队列头的“快捷方式”。DECLARE_WAIT_QUEUE_HEAD (name)3.定义等待队列。DEC...原创 2018-11-22 22:14:20 · 1727 阅读 · 0 评论