在Linux内核中,"backport printk"和"front printk"都是用于记录内核消息和调试信息的机制,但它们的工作方式和使用场景有一些区别。 "backport printk"是一种在内核中记录消息和调试信息的机制,可以将这些信息输出到控制台、串口、网络等目标。它通常用于在内核启动过程中的早期阶段,或者在没有其他可用的调试机制时使用。" backport printk"不依赖于其他内核模块或机制,因此可以在不同的环境中使用。 相比之下,"front printk"是一种将打印消息转发到用户空间的机制。 front printk"通常用于在内核中发生崩溃或错误时记录相关的信息。这些信息可以由开发人员或系统管理员稍后进行分析和故障排除。 总结来说,"backport printk"主要用于早期的内核启动阶段和没有其他调试机制的情况下,而"front printk"主要用于记录内核崩溃和错误时的信息,并将其转发到pstore机制中。
本节学习目的 1)分析printk()函数 2)使用printk()调试驱动 1.在驱动调试中,使用printk(),是最简单,最方便的办法 当uboot的命令行里的“console=tty1”时,表示 了 6.接下来,分析printk()又是如何调用s3c24xx_serial_console结构体的write(),来打印信息的 printk()函数如下所示 asmlinkage int printk /*将输出信息发送到临时缓冲区printk_buf[] */ printed_len = vscnprintf(printk_buf, sizeof(printk_buf), fmt, args 比如: printk打印级别0 ,可以输入printk(KERN_EMERG "abc");或者printk( "<0>abc"); 当printk()里没有打印级别前缀,比如printk("abc " //信息打印默认值, console_printk[1]=4 #define minimum_console_loglevel (console_printk[2]) //信息打印最小值, console_printk
git clone https://e.coding.net/weidongshan/linux/doc_and_source_for_drivers.git 视频观看 百问网驱动大全 early_printk 回顾printk的使用 2. 内核信息的早期打印 在上节视频里我们实现了console驱动,它属于uart_driver的一部分。 注册了uart_driver、并调用uart_add_one_port后,它里面才注册console,在这之后才能使用printk。 如果想更早地使用printk函数,比如在安装UART驱动之前就使用printk,这时就需要自己去注册console。 3. early_printk 源码为:arch\arm\kernel\early_printk.c,要使用它,必须实现这几点: 配置内核,选择:CONFIG_EARLY_PRINTK 内核中实现:printch
作用 通过读写/proc/sys/kernel/printk文件可读取和修改控制台的日志级别。如插入键鼠时弹出设备的输入输出msg信息等。 背景介绍 日志等级 内核通过printk() 输出的信息具有日志级别,日志级别是通过在printk() 输出的字符串前加一个带尖括号的整数来控制的,如printk("<6>Hello, world! 日志等级文件 在系统下通过读写/proc/sys/kernel/printk文件,来读取控制台的日志信息: [root@localhost ~]# cat /proc/sys/kernel/printk 这四个值是在kernel/printk.c中被定义的: int console_printk[4] = { DEFAULT_CONSOLE_LOGLEVEL, /printk [root@localhost ~]# cat /proc/sys/kernel/printk 8 1 1 1 实例 ?
("%#x ",tiny4412_usb_dev->bulk_in_buffer[n]); } printk("\n"); printk("同步提交写请求错误.错误值:%d\n",ret ("厂商ID = %#x\n",dev_info->descriptor.idVendor); //从USB设备描述符中获取厂商ID printk("设备ID = %#x\n",dev_info ->bmAttributes) { case 0:printk("端点[%d] 设备支持控制传输. \n",i);break; case 1:printk("端点[%d] 设备支持同步传输.\n",i);break; case 2:printk("端点[%d] 设备支持批量传输. \n",i);break; case 3:printk("端点[%d] 设备支持中断传输.
= %d\n",PUD_SHIFT); printk(KERN_INFO"PMD_SHIFT = %d\n",PMD_SHIFT); printk(KERN_INFO"PAGE_SHIFT printk(KERN_INFO"PTRS_PER_PUD = %d\n",PTRS_PER_PUD); printk(KERN_INFO"PTRS_PER_PMD = find_vma(pcb_tmp->mm,va)){ printk(KERN_INFO"virt_addr 0x%lx not available. *pud_tmp)); if(pud_none(*pud_tmp)){ printk(KERN_INFO"Not mapped in pud. pte_present(*pte_tmp)){ printk(KERN_INFO"pte not in RAM.
kthread\_should\_stop()) { printk(KERN\_INFO "Kernel thread is running... disk\_data) { printk(KERN\_ALERT "Failed to allocate disk data. my\_queue) { printk(KERN\_ALERT "Failed to initialize request queue. my\_disk) { printk(KERN\_ALERT "Failed to allocate gendisk. my\_input\_dev) { printk(KERN\_ALERT "Failed to allocate input device.
flash_env_dev_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg) { printk ("<1> %d\n",cmd); switch(cmd){ case 0: printk("<1> in flash 0\n"); break; case 1: printk("<1> in flash 1\n"); break; default: printk("<1> others\n" <1> fuck\n"); res=cdev_add(&flash_cdev,dev,MAX_FLASH_ENV_MINORS); if(res) printk ("<1> fuck2 \n"); /* devfs_mk_dir("flash_env_dev");*/ printk("<1> Hello World\n"); return
ppos) { unsigned char *p=kmalloc(11,GFP_KERNEL); if(copy_from_user(p,buf,10)==0) { printk flash_env_dev_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg) { printk ("<1> %d\n",cmd); switch(cmd){ case 0: printk("<1> in flash 0\n"); break; case 1: printk("<1> in flash 1\n"); break; default: printk("<1> others\n" ("<1> fuck2 \n"); /* devfs_mk_dir("flash_env_dev");*/ printk("<1> Hello World\n"); return
0:-1; } 调用: if(get_kallsyms_lookup_name() < 0){ printk(KERN_ERR "%s %s failed, load my lkm faild printk("The process vid is %d\n", (int) task_pid_vnr(current)); printk("The process name is %s\n", current->comm); printk("The process tty is %d\n", current->signal->tty); printk = 7){ printk(KERN_ERR "%s %s. current ko is not compatible for this os version. \n"); return 0; } printk("%s module load success!
bh) { printk("minix_free_block: nonexistent bitmap buffer\n"); return; } // 设置该块为空闲 if clear_bit(bit,bh->b_data)) printk("free_block (%04x:%d): bit already cleared\n",sb->s_dev,block); sb) { printk("trying to get new block from nonexistent device\n"); return 0; } repeat: j ) { printk("free_inode: inode has nlink=%d\n",inode->i_nlink); return; } if (! clear_bit(ino & 8191, bh->b_data)) printk("free_inode: bit %lu already cleared.
(copy_to_user(buf,p,10))) { printk("<1>copy ok\n"); } return 0; } static ssize_t flash_env_dev_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg) { printk ("<1> %d\n",cmd); switch(cmd){ case 0: printk("<1> in flash 0\n"); break; case 1: printk("<1> in flash 1\n"); break; default: printk("<1> others\n" ("<1> fuck2 \n"); /* devfs_mk_dir("flash_env_dev");*/ printk("<1> Hello World\n"); return
(KERN_INFO "[%s +%d] start\n", __func__, __LINE__); printk(KERN_INFO "[%s +%d] dev->init_name=%s\n ", __func__, __LINE__, dev->init_name); printk(KERN_INFO "[%s +%d] dev->driver->name=%s\n", __func __, __LINE__, dev->driver->name); printk(KERN_INFO "[%s +%d] end\n", __func__, __LINE__); return 0;}static int platform_drv_remove(struct platform_device *pdev){ printk(KERN_INFO "[%s +%d] start (KERN_INFO "[%s +%d] start\n", __func__, __LINE__); printk(KERN_INFO "[%s +%d] end\n", __func__, _
:\n"); for (int i = 0; i < 10; i++) { printk(KERN_INFO "%d ", arr[i]); } printk(KERN_INFO my_exit(void){ printk(KERN_INFO "Exiting module... ; char *dst; printk(KERN_INFO "Initializing module... }void my_exit(void){ printk(KERN_INFO "Exiting module... ; char *dst; printk(KERN_INFO "Initializing module...
用到的头文件 #include <linux/kernel.h> #include <linux/module.h> (1)初始化模块 int __init led_init(void) { printk \n"); return 0; } module_init(led_init); (2)退出模块 void __exit led_exit(void) { printk("led_exit! \n"); ret = alloc_chrdev_region(&devno,DEV_MINOR,DEV_NUM,DEV_NUM); if (ret < 0) { printk(" \n"); return -1; } } else { printk("register_chrdev_region success!!! \n"); return 0; } int led_close(struct inode *inode, struct file *file) { printk("led_close!!!
BSD/GPL"); static DEFINE_MUTEX(test_mutex); static void print_sem(struct mutex *lock) { printk :%d\n", lock,lock->count); } int reader(void *data) { char *name = (char *)data; printk (KERN_DEBUG "%s is running\n", name); mutex_lock(&test_mutex); printk(KERN_DEBUG "%s is sleeping (KERN_DEBUG "%s is running\n", name); msleep(10); mutex_lock(&test_mutex); printk( ; do_exit(0); } static int hello_init(void) { struct task_struct *task = NULL; printk
printk无锁ringbuffer的进一步优化 锁什么,不锁什么,锁大还是锁小,从来都是一个问题。宫锁心玉、宫锁珠帘、宫锁沉香、宫锁连城、宫锁printk...... 内核工程师,可能真地被printk宠坏了,printk的优势是在Linux的任意CPU、任意线程、任意中断(甚至包括NMI)都可以调用,呼之即来挥之即去。 所以Linux的printk是一个极端复杂的存在。 /7/7c/Elce-printk-v1.pdf): 第2个printk必须等第1个printk彻底完成才能开始,这个printk的效率是非常低的。 这种safe buffer的理念,也被用来避免printk自己递归(printk的实现调用printk)引起的死锁。
printk(KERN_INFO " Sum: %d\n", sum); printk(KERN_INFO " Average: %d\n", sum / numbers_count) ; printk(KERN_INFO " Max: %d\n", max); printk(KERN_INFO " Min: %d\n", min);}// 模块初始化函数static \n"); printk(KERN_INFO "param_demo: Final message: %s\n", message); printk(KERN_INFO "param_demo /test_chardev六、调试技术与最佳实践6.1 内核模块调试方法printk调试技术: printk是内核模块中最常用的调试工具,支持不同的日志级别:#include <linux/kernel.h = MAGIC_VALUE)) { printk(KERN_ERR "Corrupted object detected!
ld\t", tpc[0]); printk("[always][1]count = %ld\t", tpc[1]); printk("[always][2]count = %ld\t", tpc [0]); printk("[always][1]action_ref = %ld\t", action_ref[1]); printk("[always][2]action_ref = %ld \t", action_ref[2]); printk("[always][4]action_ref = %ld\n", action_ref[3]); printk("[always][0] ref = %ld\t", ref[0]); printk("[always][1]ref = %ld\t", ref[1]); printk("[always][2]ref = %ld\t", ref[2]); printk("[always][4]ref = %ld\n", ref[3]); printk("[always]actrefonly = %ld\n", actrefonly
gpio_get_value(MXS_PIN_TO_GPIO(PINID_SSP0_DATA6))){ //printk(KERN_INFO "key1 pressed! \n"); val = 1<<0; //A }else{ //printk(KERN_INFO "no key pressed!\n"); } if(! gpio_get_value(MXS_PIN_TO_GPIO(PINID_SSP0_DATA5))){ //printk(KERN_INFO "key2 pressed! gpio_get_value(MXS_PIN_TO_GPIO(PINID_LCD_D18))){ //printk(KERN_INFO "key4 pressed! gpio_get_value(MXS_PIN_TO_GPIO(PINID_LCD_D17))){ //printk(KERN_INFO "key5 pressed!