linux 内核保存控制台信息

来源:互联网 发布:全景图合成软件 编辑:程序博客网 时间:2024/06/05 10:16
#include <linux/module.h>#include <linux/init.h>#include <linux/fs.h>#include <linux/uaccess.h>#include <linux/slab.h>#include <linux/console.h>#include <linux/proc_fs.h>#include <linux/string.h>#include <linux/io.h>#include <linux/platform_device.h>#define DEFAULT_LOG_FILE "/data/kdebug.txt"#define DEFAULT_MAX_LEN 128*1024static char* ram_console_buffer=NULL;static size_t ram_console_buffer_len=0;static char* ram_cache_buffer=NULL;static size_t ram_cache_size=0;static size_t ram_cache_pos=0;struct work_struct write_work;static void ram_console_write(struct console *console, const char *s, unsigned int count){if((ram_cache_pos+count)<=ram_cache_size){memcpy(ram_cache_buffer+ram_cache_pos, s, count);ram_cache_pos+=count;}schedule_work(&write_work);}static ssize_t ram_console_read_old(struct file *file, char __user *buf, size_t len, loff_t *offset){if(ram_console_buffer && (ram_console_buffer_len>(*offset))){size_t cplen=min(ram_console_buffer_len-*offset, len);copy_to_user(buf, ram_console_buffer, cplen);*offset+=cplen;return cplen;}return 0;}static const struct file_operations ram_console_file_ops = {.owner = THIS_MODULE,.read = ram_console_read_old,};#define PROC_ENTRY_NAME "last_kmsg"struct proc_dir_entry* proc_entry=NULL;static struct console ram_console = {.name= "ram",.write= ram_console_write,.flags= CON_PRINTBUFFER | CON_ENABLED | CON_ANYTIME,.index= -1,};static void write_work_func(struct work_struct *data){const char* s=ram_cache_buffer;int count=ram_cache_pos;struct console* console=&ram_console;ram_cache_pos-=count;#if 1loff_t ret;mm_segment_t fs;if(NULL==console->data){return ;}ret=vfs_llseek(console->data, 0, SEEK_END);if((ret+count)>DEFAULT_MAX_LEN){ret=0;vfs_llseek(console->data, 0, SEEK_SET);}fs = get_fs();set_fs(KERNEL_DS);ret=vfs_write(console->data, s, count, &ret);set_fs(fs);#endif} static int __init ram_console_proc_init(struct console* ram_console){mm_segment_t fs;ssize_t ret;proc_entry = proc_create(PROC_ENTRY_NAME, S_IFREG | S_IRUGO, NULL, &ram_console_file_ops);if (!proc_entry) {printk(KERN_ERR "ram_console: failed to create proc entry\n");return -EFAULT;}ret=vfs_llseek(ram_console->data, 0, SEEK_END);vfs_llseek(ram_console->data, 0, SEEK_SET);if(ret>0 && ret<=DEFAULT_MAX_LEN){loff_t pos=0;ram_console_buffer=kmalloc(ret, GFP_KERNEL);ram_console_buffer[ret-1]=0;fs = get_fs();set_fs(KERNEL_DS);ret=vfs_read(ram_console->data, ram_console_buffer, ret, &pos);set_fs(fs);printk("---read last msg [%s]\n", ram_console_buffer);}printk("---read last msg ret[%d]\n", ret);proc_set_size(proc_entry, ret);ram_console_buffer_len=ret;return 0;}static int __init logdrv_init(void){struct file* fp;printk("ram_console like logdrv by cimov \n");#if 1fp=filp_open(DEFAULT_LOG_FILE, O_RDWR, 0);if(IS_ERR(fp)){fp=filp_open(DEFAULT_LOG_FILE, O_RDWR | O_CREAT, 0);if(IS_ERR(fp)){printk("can not open file %s [%#x]\n", DEFAULT_LOG_FILE, fp);return -EFAULT;}}printk("file open ok [%#x]\n", fp);#endifINIT_WORK(&write_work, write_work_func);ram_cache_buffer=kmalloc(DEFAULT_MAX_LEN, GFP_KERNEL);ram_cache_size=DEFAULT_MAX_LEN;ram_console.data=fp;ram_console_proc_init(&ram_console);printk("create proc ok\n");register_console(&ram_console);ram_console.data=fp;printk("reg console ok\n");return 0;}void __exit logdrv_exit(void){if(ram_console_buffer){kfree(ram_console_buffer);ram_console_buffer=NULL;ram_console_buffer_len=0;}filp_close(ram_console.data, NULL);unregister_console(&ram_console);remove_proc_entry(PROC_ENTRY_NAME, proc_entry);}static int ram_console_driver_probe(struct platform_device *pdev){return logdrv_init();}static struct platform_driver ram_console_driver = {.probe = ram_console_driver_probe,.driver= {.name= "ram_console",},};static struct platform_device* ram_console_device;static int __init ram_console_module_init(void){int err;err = platform_driver_register(&ram_console_driver);if(!err){ram_console_device=platform_device_alloc("ram_console", 0);if (ram_console_device) {err = platform_device_add(ram_console_device);} else {err = -ENOMEM;}if (err) {platform_device_put(ram_console_device);platform_driver_unregister(&ram_console_driver);}}return err;}//console_initcall(logdrv_init);postcore_initcall(ram_console_module_init);MODULE_LICENSE("GPL");

0 0
原创粉丝点击