内核常用函数
内核常用函数
printk 输出信息
这里使用了 printk 来输出信息,而不是 printf!因为在 Linux 内核中没有 printf 这个函数。printk 相当于 printf 的孪生兄妹,printf运行在用户态,printk 运行在内核态。在内核中想要向控制台输出或显示一些内容,必须使用printk 这个函数。不同之处在于,printk 可以根据日志级别对消息进行分类,一共有 8 个消息级别,这 8 个消息级别定义在文件 include/linux/kern_levels.h 里面,定义如下:
#define KERN_SOH "\001"
#define KERN_EMERG KERN_SOH "0" /* 紧急事件,一般是内核崩溃 */
#define KERN_ALERT KERN_SOH "1" /* 必须立即采取行动 */
#define KERN_CRIT KERN_SOH "2" /* 临界条件,比如严重的软件或硬件错误*/
#define KERN_ERR KERN_SOH "3" /* 错误状态,一般设备驱动程序中使用KERN_ERR 报告硬件错误 */
#define KERN_WARNING KERN_SOH "4" /* 警告信息,不会对系统造成严重影响 */
#define KERN_NOTICE KERN_SOH "5" /* 有必要进行提示的一些信息 */
#define KERN_INFO KERN_SOH "6" /* 提示性的信息 */
#define KERN_DEBUG KERN_SOH "7" /* 调试信息 */
一共定义了 8 个级别,其中 0 的优先级最高,7 的优先级最低。如果要设置消息级别,参考如下示例:
printk(KERN_EMERG "gsmi: Log Shutdown Reason\n");
上述代码就是设置“gsmi: Log Shutdown Reason\n”这行消息的级别为 KERN_EMERG。在具体的消息前面加上 KERN_EMERG 就可以将这条消息的级别设置为 KERN_EMERG。
如果使用 printk 的 时 候 不 显 式 的 设 置 消 息 级 别 , 那 么 printk 将 会 采 用 默 认 级 别MESSAGE_LOGLEVEL_DEFAULT,MESSAGE_LOGLEVEL_DEFAULT 默认为 4。在 include/linux/printk.h 中有个宏 CONSOLE_LOGLEVEL_DEFAULT,定义如下:
#define CONSOLE_LOGLEVEL_DEFAULT 7
CONSOLE_LOGLEVEL_DEFAULT 控制着哪些级别的消息可以显示在控制台上,此宏默认为 7,意味着只有优先级高于 7 的消息才能显示在控制台上。
这个就是 printk 和 printf 的最大区别,可以通过消息级别来决定哪些消息可以显示在控制台上。默认消息级别为 4,4 的级别比 7 高,所示直接使用 printk 输出的信息是可以显示在控制台上的。
内核和用户间的数据传递
copy_to_user()
因为内核空间不能直接操作用户空间的内存,因此需要借助 copy_to_user 函数来完成内核空间的数据到用户空间的复制。copy_to_user 函数原型如下:
static inline long copy_to_user(void __user *to, const void *from, unsigned long n)
参数 to 表示目的,参数 from 表示源,参数 n 表示要复制的数据长度。如果复制成功,返回值为 0,如果复制失败则返回负数。
copy_from_user
函数 copy_from_user 将 buf 中的数据复制到写缓冲区 writebuf 中,因为用户空间内存不能直接访问内核空间的内存,所以需要借助函数 copy_from_user 将用户空间的数据复制到 writebuf 这个内核空间中。
动态内存申请释放
kmalloc申请内存
/* 申请内存
* 如果使用的是 u32 *u32_array; 来表示数组 则需要申请内存
* 如果使用 u32 u32_array[8]; 则不需要申请内存
* 使用u32 u32_array[8]模式,前提是要知道要读取的属性有几个元素
*/
u32_array = kmalloc(elem_num * sizeof(u32), GFP_KERNEL);
if(!u32_array){
ret = -EINVAL;
printk("malloc falied!\r\n");
goto fail_malloc;
}
kfree释放内存
kfree(u32_array);
对Linux下常用头文件总结
Author@firestaradmin 2020年5月4日17:55:50
asm.current.h 定义全局项current ,其指向结构体struct task_struct
linux/sched.h 定义结构体task_struct ,只要包含此头文件即可引用当前进程
linux/modules.h 定义含有可装载模块需要的大量符号和函数
linux/init.h 定义初始化和清楚函数
linux/errno.h 定义错误编码
linux/stat.h 定义成员访问许可值
linux/sched.h 定义大部分内核API,包括睡眠函数以及各种变量声明
linux/version.h 定义内核版本信息
linux/moduleparam.h 定义用来创建模块的宏
linux/kernel.h 定义函数printf的内核代码
linux/types.h 定义dev_t ,岂作用是用来保存设备编号
linux/kdev_t.h 定义用来操作设备编号的宏
linux/fs.h 定义file_operations , file 等重要结构体,和inode结构
linux/cdev.h 定义字符设备struct cdev 结构体以及与其相关的一些辅助函数
linux/slab.h 定义内存管理的连个核心函数:*kmalloc kfree
asm/uaccess.h 定义访问用户缓冲区函数如:copy_from_user
linux/uio.h 定义iovec结构体
sys/syslog.h 定义syslogd可选值
linux/proc_fs.h 定义/proc 的模块
linux/seq_file.h 定义seq_file接口
asm/semaphore.h 定义信号量相关的东西
linux/rwsem.h 定义读取中/写入者信号量
linux/completion.h 定义complete 相关
linux/spinlock.h 定义spinlock 相关
asm/atomic.h 定义原子操作相关
asm/bitops.h 定义位操作相关(宏)
linux/seqlock.h 定义seqlock 相关
linux/rcupdate.h 定义RCU 相关(read_copy_update)
linux/ioctrl.h 定义ioctrl命令相关符号
asm/ioctrl.h 定义一些构造命令编号的宏
linux/kd.h 定义用来定义ioctrl命令的16位标量值(旧风格)
asm/uaccsee.h 定义access_ok函数(验证地址)
linux/capability.h 定义linux的全部权能操作
sys/sched.h 定义权能检查函数:capable(1C)
linux/wait.h 定义等待序列相关
linux/fcntl.h 定义I/O操作相关标志
linux/poll.h 定义poll和lelect相关
linux/param.h 定义与体系结构有关的常熟:HZ
linux/jiffies.h 定义jiffies计数器,只需包含<sys/sched.h>,会自动放入jiffies.h
linux/timex.h 定义定时相关
asm/msr.h X86专用头文件
linux/time/h 定义一些时间操作函数:do_gtetimeofday
linux/workqueue.h 定义struct workqueue_struct 结构体
linux/slab.h 定义*kmalloc(2C )函数
linux/gfp.h 定义分配内存参数标志
asm/pgtable.h 定义vmalloc(1C)可获得地址范围的连个宏
linux/percpu_counter.h 定义封装使用per_CPU变量来简历的简单整数计数器
linux/vmalloc.h 定义函数vmalloc(1C)
asm/io.h 定义I/O mapping等函数
linux/ioport.h 定义I/O 内存分配区域的接口
linux/sched.h 定义中断函数接口
linux/interrupt.h 定义中断相关
asm/page.h 定义页大小
asm/byteorder.h 定义字节序
linux/err.h 定义指针和错误值
linux/list.h 定义链表相关
linux/pci.h 定义数据传输访问配置空间函数
#include <linux/of_address.h> of_iomap()
Led字符设备驱动用到的
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/slab.h>
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!