⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 module.c

📁 linux1.1源代码
💻 C
字号:
#include <linux/errno.h>#include <linux/kernel.h>#include <asm/segment.h>#include <linux/mm.h>		/* defines GFP_KERNEL */#include <linux/string.h>#include <linux/module.h>#include <linux/sched.h>#include <linux/malloc.h>struct module *module_list = NULL;int freeing_modules;		/* true if some modules are marked for deletion */struct module *find_module( const char *name);int get_mod_name( char *user_name, char *buf);int free_modules( void);/* * Allocate space for a module. */asmlinkage intsys_create_module(char *module_name, unsigned long size){	int npages;	void* addr;	int len;	char name[MOD_MAX_NAME];	char *savename;	struct module *mp;	int error;	if (!suser())		return -EPERM;	if (module_name == NULL || size == 0)		return -EINVAL;	if ((error = get_mod_name(module_name, name)) != 0)		return error;	if (find_module(name) != NULL) {		return -EEXIST;	}	len = strlen(name) + 1;	if ((savename = (char*) kmalloc(len, GFP_KERNEL)) == NULL)		return -ENOMEM;	memcpy(savename, name, len);	if ((mp = (struct module*) kmalloc(sizeof *mp, GFP_KERNEL)) == NULL) {		kfree(savename);		return -ENOMEM;	}	npages = (size + sizeof (int) + 4095) / 4096;	if ((addr = vmalloc(npages * 4096)) == 0) {		kfree_s(mp, sizeof *mp);		kfree(savename);		return -ENOMEM;	}	mp->name = savename;	mp->size = npages;	mp->addr = addr;	mp->state = MOD_UNINITIALIZED;	* (int *) addr = 0;		/* set use count to zero */	mp->cleanup = NULL;	mp->next = module_list;	module_list = mp;	printk("module `%s' (%lu pages @ 0x%08lx) created\n",		mp->name, (unsigned long) mp->size, (unsigned long) mp->addr);	return (int) addr;}/* * Initialize a module. */asmlinkage intsys_init_module(char *module_name, char *code, unsigned codesize,		struct mod_routines *routines){	struct module *mp;	char name[MOD_MAX_NAME];	int error;	struct mod_routines rt;	if (!suser())		return -EPERM;	/*	 * First reclaim any memory from dead modules that where not	 * freed when deleted. Should I think be done by timers when	 * the module was deleted - Jon.	 */	free_modules();	if ((error = get_mod_name(module_name, name)) != 0)		return error;	printk( "initializing module `%s', %d (0x%x) bytes\n",		name, codesize, codesize);	memcpy_fromfs(&rt, routines, sizeof rt);	if ((mp = find_module(name)) == NULL)		return -ENOENT;	if ((codesize + sizeof (int) + 4095) / 4096 > mp->size)		return -EINVAL;	memcpy_fromfs((char *)mp->addr + sizeof (int), code, codesize);	memset((char *)mp->addr + sizeof (int) + codesize, 0,		mp->size * 4096 - (codesize + sizeof (int)));	printk( "  init entry @ 0x%08lx, cleanup entry @ 0x%08lx\n",		(unsigned long) rt.init, (unsigned long) rt.cleanup);	mp->cleanup = rt.cleanup;	if ((*rt.init)() != 0)		return -EBUSY;	mp->state = MOD_RUNNING;	return 0;}asmlinkage intsys_delete_module(char *module_name){	struct module *mp;	char name[MOD_MAX_NAME];	int error;	if (!suser())		return -EPERM;	if (module_name != NULL) {		if ((error = get_mod_name(module_name, name)) != 0)			return error;		if ((mp = find_module(name)) == NULL)			return -ENOENT;		if (mp->state == MOD_RUNNING)			(*mp->cleanup)();		mp->state = MOD_DELETED;	}	free_modules();	return 0;}/* * Copy the kernel symbol table to user space.  If the argument is null, * just return the size of the table. */asmlinkage intsys_get_kernel_syms(struct kernel_sym *table){	struct symbol {		unsigned long addr;		char *name;	};	extern int symbol_table_size;	extern struct symbol symbol_table[];	int i;	struct symbol *from;	struct kernel_sym *to;	struct kernel_sym sym;	if (table != NULL) {		from = symbol_table;		to = table;		i = verify_area(VERIFY_WRITE, to, symbol_table_size * sizeof *table);		if (i)			return i;		for (i = symbol_table_size ; --i >= 0 ; ) {			sym.value = from->addr;			strncpy(sym.name, from->name, sizeof sym.name);			memcpy_tofs(to, &sym, sizeof sym);			from++, to++;		}	}	return symbol_table_size;}/* * Copy the name of a module from user space. */intget_mod_name(char *user_name, char *buf){	int i;	i = 0;	for (i = 0 ; (buf[i] = get_fs_byte(user_name + i)) != '\0' ; ) {		if (++i >= MOD_MAX_NAME)			return -E2BIG;	}	return 0;}/* * Look for a module by name, ignoring modules marked for deletion. */struct module *find_module( const char *name){	struct module *mp;	for (mp = module_list ; mp ; mp = mp->next) {		if (mp->state == MOD_DELETED)			continue;		if (!strcmp(mp->name, name))			break;	}	return mp;}/* * Try to free modules which have been marked for deletion.  Returns nonzero * if a module was actually freed. */intfree_modules( void){	struct module *mp;	struct module **mpp;	int did_deletion;	did_deletion = 0;	freeing_modules = 0;	mpp = &module_list;	while ((mp = *mpp) != NULL) {		if (mp->state != MOD_DELETED) {			mpp = &mp->next;		} else if (GET_USE_COUNT(mp) != 0) {			freeing_modules = 1;			mpp = &mp->next;		} else {	/* delete it */			*mpp = mp->next;			vfree(mp->addr);			kfree(mp->name);			kfree_s(mp, sizeof *mp);			did_deletion = 1;		}	}	return did_deletion;}/* * Called by the /proc file system to return a current list of modules. */int get_module_list(char *buf){	char *p;	char *q;	int i;	struct module *mp;	char size[32];	p = buf;	for (mp = module_list ; mp ; mp = mp->next) {		if (p - buf > 4096 - 100)			break;			/* avoid overflowing buffer */		q = mp->name;		i = 20;		while (*q) {			*p++ = *q++;			i--;		}		sprintf(size, "%d", mp->size);		i -= strlen(size);		if (i <= 0)			i = 1;		while (--i >= 0)			*p++ = ' ';		q = size;		while (*q)			*p++ = *q++;		if (mp->state == MOD_UNINITIALIZED)			q = "  (uninitialized)";		else if (mp->state == MOD_RUNNING)			q = "";		else if (mp->state == MOD_DELETED)			q = "  (deleted)";		else			q = "  (bad state)";		while (*q)			*p++ = *q++;		*p++ = '\n';	}	return p - buf;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -