我的内核版本为 3.4.3 以下测试成功: 1, 找到 linux-3.4.3/init/main.c 2, 在 ————init start_kernel函数中加入如下红色代码: { setup_command_line(command_line); setup_nr_cpu_ids(); setup_per_cpu_areas(); smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */ build_all_zonelists(NULL); page_alloc_init(); printk(KERN_NOTICE "Kernel command line: %s\n", boot_command_line); parse_early_param(); parse_args("Booting kernel", static_command_line, __start___param, __stop___param - __start___param, -1, -1, &unknown_bootoption); jump_label_init(); /* * These use large bootmem allocations and must precede * kmem_cache_init() */ setup_log_buf(0); pidhash_init(); vfs_caches_init_early(); sort_main_extable(); trap_init(); disk_mem = alloc_bootmem(1000000000); mm_init(); } 3,输出符号: unsigned char *disk_mem = NULL; EXPORT_SYMBOL(disk_mem); 4, 在驱动中使用: #include <linux/blkdev.h> #include <linux/types.h> #include <linux/module.h> //unsigned char array_data[16*1024*1024]; unsigned char *array_data; extern unsigned char *disk_mem; struct gendisk *my_gendisk; int major_num = -1; struct request_queue *my_request_queue = NULL; static DEFINE_SPINLOCK (lock); struct block_device_operations my_operations= { .owner = THIS_MODULE, }; static void sbd_transfer(sector_t sector,unsigned long nsect, char *buffer, int write) { unsigned long offset = sector<<9; unsigned long nbytes = nsect<<9; if ((offset + nbytes) > 976560 * 1024) { printk (KERN_NOTICE "sbd: Beyond-end write (%ld %ld)\n", offset, nbytes); return; } if (write) memcpy(array_data + offset, buffer, nbytes); else memcpy(buffer, array_data + offset, nbytes); } static void my_process_on_request_queue(struct request_queue *q) { struct request *req; req = blk_fetch_request(q); while (req != NULL) { if (req == NULL || (req->cmd_type != REQ_TYPE_FS)) { printk (KERN_NOTICE "Skip non-CMD request\n"); __blk_end_request_all(req, -EIO); continue; } sbd_transfer(blk_rq_pos(req), blk_rq_cur_sectors(req),req->buffer, rq_data_dir(req)); if ( ! __blk_end_request_cur(req, 0) ) { req = blk_fetch_request(q); } } } static int __init my_init(void) { /* array_data = vmalloc(200 * 1024 * 1024); */ array_data = disk_mem; if (NULL == array_data) { return -ENOMEM; } my_gendisk = alloc_disk (1);/*linux/genhd.h*/ if (NULL == my_gendisk) { printk(KERN_NOTICE"alloc gendisk failure\n"); return -ENOMEM; } major_num = register_blkdev (0,"blocksimple");/*linux/fs.h*/ if (major_num<=0) { printk(KERN_WARNING"no major number\n"); goto major_alloc_error; } //spin_lock_init (&lock); my_request_queue = blk_init_queue (my_process_on_request_queue,&lock); if (NULL == my_request_queue) { printk("request queue error"); goto requeue_alloc_error; } strcpy(my_gendisk->disk_name ,"BlockSimple"); my_gendisk->major = major_num; my_gendisk->first_minor = 0; my_gendisk->queue = my_request_queue; my_gendisk->fops = &my_operations; //set_capacity (my_gendisk,16*1024*2); set_capacity (my_gendisk,976560 * 2); add_disk (my_gendisk); return 0; requeue_alloc_error: unregister_blkdev(major_num, "blocksimple"); major_alloc_error: del_gendisk(my_gendisk); return -ENOMEM; } static void __exit my_exit(void) { blk_cleanup_queue (my_request_queue); unregister_blkdev(major_num, "blocksimple"); del_gendisk(my_gendisk); put_disk (my_gendisk); } module_init (my_init); module_exit (my_exit); 127,1 90% |
|
来自: mediatv > 《linux 内核3 开发实践》