何把内核中的信息打印到文件
时间:2008-01-16 13:09:57 来源: 作者:
|
我在内核中加了几个函数,要输出一些数据到文件中,以便处理,请问内核中提供了输出到文件的函数了么?谢谢! albcamus 回复于:2006-04-13 13:54:16
xiaozhe2000 回复于:2006-04-13 14:21:14 谢谢斑竹!!!:P mq110 回复于:2006-04-13 14:36:17 我给你个打印在屏幕上的. mq110 回复于:2006-04-13 14:38:59 [CODE] #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/sched.h> #include <linux/tty.h> MODULE_LICENSE("GPL"); MODULE_AUTHOR("mq110"); static void print_string(char *str) { struct tty_struct *my_tty; my_tty = current->signal->tty; if (my_tty != NULL) { my_tty->driver->write(my_tty,0,str,strlen(str)); my_tty->driver->write(my_tty,0," 15 13",2); } } static int __init print_string_init(void) { print_string("Hello world!"); return 0; } static void __exit print_string_exit(void) { print_string("Goodbye world!"); } module_init(print_string_init); module_exit(print_string_exit); [/CODE] 我一般用putty登陆 编写kernel module. printk信息都存在/var/log/message里了.~ 用这个程序就能显示在屏幕上了.你可以把print_string 符号导出来. 思一克 回复于:2006-04-13 15:30:19 直接用PRINTK,然后在MESSAGES中选出来多好。 自己写的使用范围小(加入内核的函数会被其它函数调用,大部分情况不是mod_init直接调用的)。死机的情况多。printk则好多了。 maluyao 回复于:2006-04-13 17:14:01 修改一下/etc/syslog.conf 文件 #kern.* /dev/console 你打印的东西可能是某个级别的信息。比如说debug,这用printk 可以控制 。 那么就写程 kern.debug /var/log/kern_debug.log ------------------------- printk(KERN_ALERT "Hello, worldn"); 对应 /etc/syslog.conf 中的 kern.alert /kernel.txt 实验成功,修改后要执行 server syslogd restart 重启日志服务。 此方法等于用日志服务帮你做这个事情。该信息用 dmesg 命令也可以看到。 [ 本帖最后由 maluyao 于 2006-4-13 17:31 编辑 ] tomorrow0530 回复于:2006-04-20 14:17:32 引用:原帖由 思一克 于 2006-4-13 15:30 发表 直接用PRINTK,然后在MESSAGES中选出来多好。 自己写的使用范围小(加入内核的函数会被其它函数调用,大部分情况不是mod_init直接调用的)。死机的情况多。printk则好多了。 死机!!哈哈,我的就是这样!:em10: 我把对文件的操作包了一层,以模块形式加载,把操作函数导出。 然后注册了个钩子函数,使用导出的函数,希望将包的信息写到指定文件。 情况时好时坏,有时一加载钩子函数就死机,有时多刷几次163之类的也死机。。。。 这个死机问题有没有解决的方法阿?谢谢 albcamus 回复于:2006-04-20 14:24:37 引用:原帖由 tomorrow0530 于 2006-4-20 14:17 发表 死机!!哈哈,我的就是这样!:em10: 我把对文件的操作包了一层,以模块形式加载,把操作函数导出。 然后注册了个钩子函数,使用导出的函数,希望将包的信息写到指定文件。 情况时好时坏,有时一加载钩子 ... 你hook的是什么函数? tomorrow0530 回复于:2006-04-20 14:42:46 自己写的,贴上来,个个提点意见了。。。。 #define __KERNEL__ #define MODULE #include <linux/module.h> #include <linux/kernel.h> //NIPQUAD() #include <linux/netdevice.h> //struct net_device #include <linux/netfilter.h> #include <linux/netfilter_ipv4.h> #include <linux/ip.h> #include <linux/tcp.h> #include <linux/in.h> //IPPROTO_TCP static struct nf_hook_ops nfho; static char *drop_if = "lo"; unsigned int hook_func(unsigned int hooknum, struct sk_buff **skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { if (strcmp(in->name, drop_if) != 0) { static const char nulldevname[IFNAMSIZ]={0}; struct sk_buff *sb = *skb; static unsigned int target_ip = 0; static unsigned short target_port = 0; static unsigned int source_ip = 0; static unsigned short source_port = 0; static char *in_dev_name = ""; static char *out_dev_name = ""; struct file *filp; struct iphdr *ip; struct tcphdr *tcp; ip = sb->nh.iph; tcp = (struct tcphdr *)(sb->data + (sb->nh.iph->ihl * 4)); in_dev_name = in?in->name:nulldevname; out_dev_name = out?out->name:nulldevname; source_ip = ip->saddr; target_ip = ip->daddr; target_port = ((((tcp->dest) >> 8 ) & 0xff )|(((tcp->dest) & 0xff) << 8)); source_port = ((((tcp->source) >> 8 ) & 0xff )|(((tcp->source) & 0xff) << 8)); if ((filp = klib_fopen("/root/logfile", O_APPEND|O_WRONLY, S_IRUSR | S_IWUSR)) == NULL) { printk("Can't open filen"); return NF_ACCEPT; } if(ip->protocol == IPPROTO_TCP) { klib_fprintf(filp,"Accepted TCP packet in_dev_name:%s out_dev_name:%s MAC:", in_dev_name, out_dev_name); if ((sb)->dev && (sb)->dev->hard_header_len && (sb)->mac.raw != (void*)ip) { int i; unsigned char *p = (sb)->mac.raw; for (i = 0; i < (sb)->dev->hard_header_len; i++,p++) klib_fprintf(filp,"%02x%c", *p, i==(sb)->dev->hard_header_len - 1 ? ' ':':'); } else klib_fputc(' ', filp); klib_fprintf(filp," source_ip:%u.%u.%u.%u target_ip:%u.%u.%u.%u source_port:%u target_port:%un", NIPQUAD(source_ip), NIPQUAD(target_ip), source_port, target_port); klib_fprintf(filp," TCPn"); }else klib_fprintf(filp," NOT TCPn"); klib_fclose(filp); } return NF_ACCEPT; } static int init_func() { nfho.hook = hook_func; nfho.hooknum = NF_IP_PRE_ROUTING; nfho.pf = PF_INET; nfho.priority = NF_IP_PRI_FIRST; nf_register_hook(&nfho); return 0; } static void cleanup_func() { nf_unregister_hook(&nfho); } module_init(init_func); MODULE_LICENSE("GPL"); module_exit(cleanup_func); albcamus 回复于:2006-04-20 14:47:51 netfilter的hook点是在softirq的上下文中, 不可以睡眠(亦即:阻塞当前进程), 读写磁盘文件恰恰是可能导致睡眠的。 记得wheelz斑竹的建议是: 如果你一定要在softirq上下文中读写文件, 那么, 生成一个内核线程来做这件事。 tomorrow0530 回复于:2006-04-20 15:00:27 哦,原来是这样啊! 内核线程没有写过,先去补补这方面的东西! 有什么问题再过来请教各位了! 谢谢 思一克 回复于:2006-04-20 15:15:34 换成printk tomorrow0530 回复于:2006-04-20 15:37:08 之前写了个用printk的,但因为和许多别的信息混在messages里,所以才想把它单独写到别的文件中! 思一克 回复于:2006-04-20 15:40:19 PRINTK的每行前加一个标志MYLOG, 然后grep到一个文件中不就可以了吗 tomorrow0530 回复于:2006-04-20 15:47:40 这也是个不错的办法!! 马上试试去! 谢谢了 思一克 回复于:2006-04-20 16:11:00 printk也不是放什么地方都可以。它调用wake_up_XXXXXXXX了。实验着看。 albcamus 回复于:2006-04-20 16:40:16 printk在哪里都可以用的:) 思一克 回复于:2006-04-20 16:53:06 to alb, 放有些函数中不可以。比如和schedule()有关的函数,比如要switch context的许多地方,立即死机。 还有些地方(中断),理论上可以用,但实际随机地死机。 albcamus 回复于:2006-04-21 09:51:24 引用:原帖由 思一克 于 2006-4-20 16:53 发表 to alb, 放有些函数中不可以。比如和schedule()有关的函数,比如要switch context的许多地方,立即死机。 还有些地方(中断),理论上可以用,但实际随机地死机。 以前没遇到过呢, 有空试验下:) snow_insky 回复于:2006-04-21 11:36:22 不是吧,还这么老土,内核中已经提供了相应的函数,以便于在内核里操作文件,它们是: filp_open,filp_close等,你自己找一下。不用自己写了。 tomorrow0530 回复于:2006-04-21 13:42:47 试验结果,在hook函数上使用printk,没有问题。别的地方还没有试!! 用grep也很方便,谢谢思一克的点子!! tomorrow0530 回复于:2006-04-21 13:45:34 我说的那个就是把filp_open之类的包了一层,导出后。 用起来比较方便,不用包含头文件,就直接使用。 思一克 回复于:2006-04-21 13:52:10 filp_open不行。楼主早都是这样做的。 tomorrow0530 回复于:2006-04-21 14:41:01 在hook函数里用,filp_open之类的函数会造成死机!我的亲身体验,原因楼上的alb......已经说了! [ 本帖最后由 tomorrow0530 于 2006-4-21 14:43 编辑 ] obrire 回复于:2006-04-24 23:51:34 没有不行的,我在内核多处使用,可以在用户间分类写很多文件 别是你VFS都没起来吧,那就麻烦了 你还可以采用procfs/relayfs/sysfs等记录嘛。 printk也行,因为一般是要初始化串口的/Bootloader和Kernel都要先做这事。 如果没有串口初始化呢? 采用其它文件格式记录也行的。 以上操作就是臭名昭著的克拉克Trojan一部分 snow_insky 回复于:2006-04-25 09:33:50 我们的DSP镜像就是用filp_open之类的函数加载的,是不是自己不会用,就在这里说不行,唉,世道炎凉。 不仔细研究,就自己没搞出来就说不行。 huyongzs 回复于:2006-04-25 15:07:58 诸位高手,你们发的这些代码怎么编译啊? 我用的是 gcc -g -o kprinter kernelprinter.c 不行啊,出现错误。 albcamus 回复于:2006-04-25 15:42:35 >>如果没有串口初始化呢? /dev/console初始化之前,可以用early_printk打印信息。 to huyongzs: >>gcc -g -o kprinter kernelprinter.c 2.4和2.6编译过程不一样。 如果是前者, 去掉-g试试; 后者的话看精华区的文档吧(我转贴的ibm站点的那篇) zhangjiakouzf 回复于:2006-04-29 13:55:15 引用:原帖由 huyongzs 于 2006-4-25 15:07 发表 诸位高手,你们发的这些代码怎么编译啊? 我用的是 gcc -g -o kprinter kernelprinter.c 不行啊,出现错误。 是不是应该加上-c选项呀 -c: 一个内核模块不是一个独立的可执行文件,而是一个内核在运行时用insmod动态连结的 目标文件。所以,内核应该在编译时使用 -c 选项。 obrire 回复于:2006-04-30 00:53:00 引用:原帖由 albcamus 于 2006-4-25 15:42 发表 >>如果没有串口初始化呢? /dev/console初始化之前,可以用early_printk打印信息。 to huyongzs: >>gcc -g -o kprinter kernelprinter.c 2.4和2.6编译过程不一样。 如果是前者, 去掉-g试试; ... 在没有初始化串口时,在寄存器中,置入字符及输入,需要一些基本的转换 输入的全为字符,需将其转换为相对应的数据类型. 因此,在所有的Bootloader中,都几乎要做这一步. 不管在任何时候,需要操作串口接口,可以自己写一个操作函数.不管在任何时候 都可以输出.好像设置相关寄存器只有几句话.看三星和Moto的都这样. -g 是包括调试信息之意. 如使用/dev/console,也就是/dev/tty(Sxx)等,都是在串口驱动启动以后; 之前,有一小段初始化串口代码,就是几句置数寄存器操作.而直接操作物理 接口,不受任何限制.以前我们都这样做的.包括下载Bootloader及调试.这时 没有任何输出,不可能用逻辑分析仪吧.不累死了. 但一般来讲,在内核空间是可以用文件操作的,因为VFS是Built-in内核的,大多数 情况是必须的. Cbook 回复于:2006-05-07 10:50:45 请教为什么上面的例子程序我都编译不过去啊 我用的是gcc -g -c -O -Wall XXX.c linux_ha 回复于:2007-09-24 17:24:57 用/proc就可以免去file_open的问题吧?:em21: hongmy525 回复于:2007-12-03 14:01:47 引用:原帖由 思一克 于 2006-4-20 15:40 发表 [url=http://linux.chinaunix.net/bbs/redirect.php?goto=findpost&pid=5048093&ptid=738197]
PRINTK的每行前加一个标志MYLOG, 然后grep到一个文件中不就可以了吗 用处多多,谢谢:) |
原文链接:http://linux.chinaunix.net/bbs/viewthread.php?tid=738197 转载请注明作者名及原文出处 |
上一篇: 使用 /proc 文件系统来控制系统










文章评论
共有 位网友发表了评论 查看完整内容