kernel misc
. include/linux/string.h
在kernel里使用string类的函数,比如strstr()等,这些函数声明在include/linux/string.h,include <linux/string.h>即可
. /dev/tty, tty driver blog
http://www.mysixue.com/?p=127#devconsole_devtty0_devtty1
. log ratelimit
ratelimit_state_init()
例如如下ratelimit_state_init()是设置5s内打印10条msg:
#define DEFAULT_RATELIMIT_INTERVAL (5 * HZ)
#define DEFAULT_RATELIMIT_BURST 10
static inline void ratelimit_default_init(struct ratelimit_state *rs)
{
return ratelimit_state_init(rs, DEFAULT_RATELIMIT_INTERVAL,
DEFAULT_RATELIMIT_BURST);
}
. kernel makefile desc
https://blog.51cto.com/weiguozhihui/1591397
. set_task_comm(tsk, "kthreadd");
. android在init.rc里将panic_on_oops默认设置为了1
write /proc/sys/kernel/panic_on_oops 1
. __ffs
获取二进制形式数值第一个非0bit,从低位往高位检查,index从0开始:
unsigned long bitmap = 0x90911010;
/* first bit */
printk("Bitmap: %#lx __ffs(): %ld
", bitmap, __ffs(bitmap));
执行结果:
Bitmap: 0x90911010 __ffs(): 4
size_t/ssize_t type definition
4.19includelinux ypes.h #ifndef _SIZE_T #define _SIZE_T typedef __kernel_size_t size_t; #endif #ifndef _SSIZE_T #define _SSIZE_T typedef __kernel_ssize_t ssize_t; #endif
4.19includeuapiasm-genericposix_types.h #ifndef __kernel_size_t #if __BITS_PER_LONG != 64 typedef unsigned int __kernel_size_t; typedef int __kernel_ssize_t; typedef int __kernel_ptrdiff_t; #else typedef __kernel_ulong_t __kernel_size_t; typedef __kernel_long_t __kernel_ssize_t; typedef __kernel_long_t __kernel_ptrdiff_t; #endif #endif
CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT
CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT: Temporary per-CPU printk log buffer size (12 => 4KB, 13 => 8KB)
The Linux kernel configuration item CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT
:
- prompt: Temporary per-CPU printk log buffer size (12 => 4KB, 13 => 8KB)
- type: int
- depends on:
CONFIG_PRINTK
- defined in init/Kconfig
- found in Linux kernels: 4.11–4.20, 5.0–5.13, 5.13+HEAD
Help text
Select the size of an alternate printk per-CPU buffer where messages printed from usafe contexts are temporary stored. One example would be NMI messages, another one - printk recursion. The messages are copied to the main log buffer in a safe context to avoid a deadlock. The value defines the size as a power of 2.
Those messages are rare and limited. The largest one is when a backtrace is printed. It usually fits into 4KB. Select 8KB if you want to be on the safe side.
Examples: 17 => 128 KB for each CPU 16 => 64 KB for each CPU 15 => 32 KB for each CPU 14 => 16 KB for each CPU 13 => 8 KB for each CPU 12 => 4 KB for each CPU
from: https://cateee.net/lkddb/web-lkddb/PRINTK_SAFE_LOG_BUF_SHIFT.html
Linux kernel中的IS_ENABLED
首先在Kconfig中选中某个选项为y或m时, 在.config文件中就会由一个CONFIG_XXXXX=y或CONFIG_XXXXX=m, 并且会自动生成一个头文件autoconfig.h. 当选中为y时, 头文件中包含#define CONFIG_XXXXX 1, 当选中为m时, 头文件中包含#define CONFIG_XXXXX_MODULE 1, 当不选中是, 头文件中不包含相关语句.
from: https://blog.csdn.net/gngshn/article/details/69790798
在kernel里读一个文件(比如一个ko)
使用kernel_read_file_from_fd(),根据fd来read:
SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags) { struct load_info info = { }; void *hdr = NULL; int err; err = may_init_module(); if (err) return err; pr_debug("finit_module: fd=%d, uargs=%p, flags=%i ", fd, uargs, flags); if (flags & ~(MODULE_INIT_IGNORE_MODVERSIONS |MODULE_INIT_IGNORE_VERMAGIC)) return -EINVAL; err = kernel_read_file_from_fd(fd, 0, &hdr, INT_MAX, NULL, READING_MODULE); if (err < 0) return err; info.hdr = hdr; info.len = err; return load_module(&info, uargs, flags); }
kernel延时函数
mdelay()
这个属于忙等待,不会让出CPU
msleep()
这个调用了后会让出CPU,不会忙等待
usleep_range(min, max)
这个调用了后会让出CPU,不会忙等待
/proc/kallsyms
如果只开了CONFIG_KALLSYMS,CONFIG_KALLSYMS_ALL没开,则/proc/kallsyms里将只会有函数symbol,全局变量symbol将没有。
kernel里读memory,比如dump一个寄存器指向的memory前后的数据
如下是一个示例,一次读16byte:
unsigned char buf[16] = {0}; if(!probe_kernel_read(buf,(const void *)task_struct_addr,sizeof(buf)))
list_for_each_entry()相关的操作都需要放在这个循环体里,如果是遍历了一遍,它会返回head,此时如果指向回了head,此循环将会结束,此时如果在循环体外有对p的相关操作,会导致debug异常call到brk_handler:
list_for_each_entry(p, &mali_cmar_files_list, node) { if(p->pid == tsk->pid) { if(once) { once = 0; pr_info("unregister 0x%px files_struct ptr. ", &tsk->files); unregister_wp_bp((unsigned long)&tsk->files); } list_del_init(&p->node); kfree(p); p = NULL; break; } }
打印调用者
printk("caller is %pS ", __builtin_return_address(0));
打印结果:
[ 102.549872] caller is exit_files+0x150/0x310