PROC介绍,和PROC在线调试LCM以及dmesg && EXPORT_SYMBOL的用法
来源:互联网 发布:apache tomcat 闪退 编辑:程序博客网 时间:2024/06/11 12:07
proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。它以文件系统的方式为访问系统内核数据的操作提供接口。用户和应用程序可以通过proc得到系统的信息,并可以改变内核的某些参数。由于系统的信息,如进程,是动态改变的,所以用户或应用程序读取proc文件时,proc文件系统是动态从系统内核读出所需信息并提交的。它的目录结构包括普通常用目录和数字命名目录:
(1) 用户如果要查看系统信息,可以用cat命令。例如:# cat /proc/interrupts 。
cmdline :内核命令行
Cpuinfo :关于Cpu信息
Devices :可以用到的设备(块设备/字符设备),可通过cat /proc/devices得到主设备号和设备名
Filesystems :支持的文件系统
Interrupts :中断的使用
Ioports I/O:端口的使用
Kmsg :内核消息
Ksyms :内核符号表
Loadavg :负载均衡
Locks :内核锁
Meminfo :内存信息
Misc :杂项
Modules :加载模块列表
Mounts :加载的文件系统
Partitions :系统识别的分区表
Rtc :实时时钟
Slabinfo Slab:池信息
Stat :全面统计状态表
Swaps :对换空间的利用情况
Version :内核版本
Uptime :系统正常运行时间
并不是所有这些目录在你的系统中都有,这取决于你的内核配置和装载的模块。另外,在/proc下还有三个很重要的目录:net,scsi和sys。 Sys目录是可写的,可以通过它来访问或修改内核的参数来优化你的系统。但是你必须很小心,因为可能会造成系统崩溃。而net和scsi则依赖于内核配置。例如,如果系统不支持scsi,则scsi 目录不存在。
(2)除了以上介绍的这些,还有的是一些以数字命名的目录,它们是进程目录。系统中当前运行的每一个进程都有对应的一个目录在/proc下,以进程的 PID号为目录名,它们是读取进程信息的接口。而self目录则是读取进程本身的信息接口,是一个link。Proc文件系统的名字就是由之而起。每个进程目录的结构如下:
目录名称 目录内容
Cmdline 命令行参数
Environ 环境变量值
Fd 一个包含所有文件描述符的目录
Mem 进程的内存被利用情况
Stat 进程状态
Status 进程当前状态,以可读的方式显示出来
Cwd 当前工作目录的链接
Exe 指向该进程的执行命令文件
Maps 内存映象
Statm 进程内存状态信息
Root 链接此进程的root目录
(3)正因为采用PROC可以访问linux的内核设备信息,可以采用此种方式在线调试LCM。
A,首先在帧缓冲驱动中创建proc文件系统。头文件申明:
#define LCM_ONLINE_TUNNING#if defined (LCM_ONLINE_TUNNING)#include <linux/proc_fs.h> //proc file use #endif
B,外部申明Proc的读写函数
#if defined (LCM_ONLINE_TUNNING)extern int LCM_HW_DumpReg_To_Proc(char *page, char **start, off_t off,int count, int *eof, void *data);extern int LCM_HW_Reg_Debug( struct file *file, const char *buffer, unsigned long count,void *data);#endif
C,在帧缓冲的PROBE函数中,创建PROC。
#if defined (LCM_ONLINE_TUNNING)struct proc_dir_entry *prEntry; prEntry = create_proc_entry("driver/lcm", 0, NULL);//在/proc创建路径 if (prEntry) { prEntry->read_proc = LCM_HW_DumpReg_To_Proc; prEntry->write_proc = LCM_HW_Reg_Debug; } else { printk("add /proc/driver/lcm entry fail \n"); }#endif
D,在AP显示驱动中添加读写函数原型
#define LCM_ONLINE_TUNNING#if defined (LCM_ONLINE_TUNNING)#include <linux/uaccess.h>#endif
E,proc写函数原型
#if defined (LCM_ONLINE_TUNNING)int LCM_HW_DumpReg_To_Proc(char *page, char **start, off_t off,int count, int *eof, void *data){ return count;}int LCM_HW_Reg_Debug( struct file *file, const char *buffer, unsigned long count,void *data){ char regBuf[512] = {'\0'} ;char temp[256]={0}; u32 u4CopyBufSize = (count < (sizeof(regBuf) - 1)) ? (count) : (sizeof(regBuf) - 1);unsigned int RegAddr;unsigned int RegData[256];char *p = regBuf;int i = 0,param_count = 0; if (copy_from_user(regBuf, buffer, u4CopyBufSize))//读入echo的字符串 return -EFAULT; printk("param : %s\n",regBuf);//打印echo的字符串 sscanf(regBuf, "%2s", temp) ;//取regBuf的头两个字符存于temp中 sscanf(temp, "%0x", &RegAddr);//格式化字符串的头两个字符,转成寄存器地址 printk("cmd index : %0x",RegAddr); while((p = strchr(p,' ')) !=NULL) {//依次导入该地址要写入的数据p++;sscanf(p, "%2s", temp);sscanf(temp, "%0x", &RegData[i]);printk("Cmd data : %0x",RegData[i]);i++;param_count++; }i = 0;printk("param count : %d\n",param_count);lcm_utils.send_cmd(RegAddr) ;//调用地址写入函数while(i < param_count) {lcm_utils.send_data(RegData[i]) ;//调用数据写入函数i++;} return count; }#endif
F,调试语句:
如下,连上ADB后,可以单行调试,也可以一次写入多行。第一个是寄存器地址,后面的则是参数。
echo "f1 36 04 00 3c 0f 8f" > /proc/driver/lcm
echo "f2 18 A3 12 02 72 32 FF 12 00" > /proc/driver/lcm
echo "f8 21 04" > /proc/driver/lcm
echo "f9 00 08" > /proc/driver/lcm
echo "36 48" > /proc/driver/lcm
echo "b4 02" > /proc/driver/lcm
G,DSI的写语句:
以上是DBI的在线调试方法,如果是DSI接口的,则用下面的语句把最后的发送指令及while循环替换掉即可。
lcm_utils.dsi_set_cmdq_V2(RegAddr,param_count,RegData,1);
(4)dmesg也可用来查看内核信息,一般用来显示开机信息,kernel会将开机信息存储在ring buffer中。您若是开机时来不及查看信息,可利用dmesg来查看。另一个用途是查看insmod的打印消息。
=================================================================================================
EXPORT_SYMBOL的一个用法,仅针对module。在MTK的编译系统中,不同驱动之间互相引用变量,直接跟普通C一样采用extern申明就可以访问。但是如果某个模块编译采用的是make中的oby+m,而不是默认的obj-y,这种引用变量的方式编译会出错。
EXPORT_SYMBOL既可以用来导出模块函数,也可以导出模块变量。举一个简单的模块变量的用法:
hello.c:
#include <linux/init.h>#include <linux/module.h>MODULE_LICENSE("Dual BSD/GPL");int symbol_lxp = 123;EXPORT_SYMBOL(symbol_lxp);static int hello_init(void){printk(KERN_ALERT "Hello, World!\n");return 0;}static void hello_exit(void){printk(KERN_ALERT "Goodbye, cruel world!\n");}module_init(hello_init);module_exit(hello_exit);
hello2.c:
#include <linux/init.h>#include <linux/module.h>MODULE_LICENSE("Dual BSD/GPL");extern int symbol_lxp;static int hello2_init(void){printk(KERN_ALERT "Hello2, World!\n");printk("symbol_lxp defined in hello.ko: symbol_lxp = %d\n", symbol_lxp);return 0;}static void hello2_exit(void){printk(KERN_ALERT "Goodbye2, cruel world!\n");}module_init(hello2_init);module_exit(hello2_exit);
运行结果:在hello2.ko中可以使用hello.ko中导出的变量
[root@(none)/mnt]#insmod hello.ko
Hello, World!
[root@(none)/mnt]#insmod hello2.ko
Hello2, World!
symbol_lxp defined in hello.ko: symbol_lxp = 123
参考原文:http://blog.csdn.net/xiangpingli/article/details/7917931
- PROC介绍,和PROC在线调试LCM以及dmesg && EXPORT_SYMBOL的用法
- PROC文件系统介绍 &&以PROC在线调试LCM && EXPORT_SYMBOL的用法
- Linux PROC文件系统详细介绍 && EXPORT_SYMBOL的用法
- 内核调试 /proc/kmsg 和 dmesg
- 增加/proc/kmsg和dmesg的信息容量的方法
- 内存以及/proc/介绍
- /dev和/proc介绍
- /dev和/proc介绍
- /PROC 调试
- Core Dump和/proc调试
- proc介绍
- linux 的proc文件系统介绍
- ORACLE的ProC用法讲解
- Linux调试中使用的proc和sys中的接口
- proc
- proc
- /proc
- proc
- 系统架构师的修炼 (转载)
- 一学生用Java写的雷电游戏[经典]
- 架构师要了解那些 (转载)
- Google 將與手機製造商翻臉嗎?
- 架构师的思考 (转载)
- PROC介绍,和PROC在线调试LCM以及dmesg && EXPORT_SYMBOL的用法
- 架构师的思考 - 估算的技巧 (转载)
- 做一位出色的架构师 (转载)
- SQL SERVER中关于NULL的设定
- POJ2255 解题报告
- Shell编程基础 (转载)
- Linux常用脚本
- 某市120项目工作感想——另外一个角度的思考
- 网桥、网关、交换机、中继器与路由器之间的区别以及所处的层 (转载)