linux下模块加载的一些问题

一开始 编译模块时,使用了gcc,搞出了笑话哈哈,不了解模块的基本内容了
1.写完一段模块程序后,包括作基本的module_init(globalmem_init)和module_exit(globalmem_exit)等;
2.写一个基本的makefile文件,来进行编译;
3.运行make(makefile中已写入了生成模块的命令),生成globalmem.ko模块;
4.两个方式加载模块:insmod globalmem.ko 和将globalmem.ko复制到/lib/modules/2.6.23.1-42.fc8/下,运行 
depmod -a 命令生成模块依赖关系写入module
.dep,最后运行modprobe globalmem命令;
ok!



以下参考:http://www.ajaxstu.com/neiheyuanma/270873.html 多谢 在网上找了好久阿
linux下加载模块的两个命令 modprobe 和insmod
1. modprobe能自动处理模块间的依赖关系。在安装一个模块时,能自动安装该模块所需的其它模块;insmod加载时不需要
依赖的模块,直接加载模块。
2. modprobe加载时,先将要加载的模块放入模块搜索路径(我的放在/lib/modules/2.6.23.1-42.fc8/下);
再运行depmod -a(depmod -a,它是生成相关依赖并写如到module.dep中
;再运行modprobe xx即可。
3. insmod加载时,只需要进入模块所在目录,运行命令insmod xx.ko即可


关于在字符设备中建立设备节点的问题:
在使用insmod进行模块加载时,如果程序中未在处理,应手动使用命令mknod /dev/xxx c 250 0 进行设备节点的建立;
在udev中可以使用函数进行自动建立设备节点 (Linux 内核为我们提供了一组函数,可以用来在模块加载的时候自动在
/dev目录下创建相应设备节点,并在卸载模块时删除该节点,当然前提条件是用户空间移植了udev。)

具体在globalmem_init()函数中加入

///-----------------------------------------------------
/* create your own class under /sysfs */
globalmem_class = class_create(THIS_MODULE, "globalmem");
if(IS_ERR(globalmem_class))
{
printk("Err: failed in creating class./n");
return -1;
}
/* register your own device in sysfs, and this will cause udev to create corresponding device node */
device_create(globalmem_class, NULL, MKDEV(globalmem_major, 0), "globalmem",0);
printk (KERN_INFO "Registered character driver/n");

//----------------------------------------------------
在globalmem_exit()函数中加入

//---------------------
device_destroy(globalmem_class,MKDEV(globalmem_major,0));
class_destroy(globalmem_class);
//---------------------




看似终于对globalmem这个虚拟字符设备有了部分的了解了,现在总结一下一些很可笑的错误:
1. 对于echo的了解 使用ehco ‘hello’>/dev/xxx 后会自动在/dev目录下生成一个普通的文件,一开始搞不懂,以为不需要   建立设备节点就可以使用echo测试了,还是需要手动建立设备节点或在程序中添加建立设备节点的代码。
2. 出现如下的一个错误,在网上怎么都搜不到的
bash: echo: write error: 无效的参数
后来下了源代码测试没问题,
这是编译时出现的警告 /root/driver/globalmem/globalmem.c:85: 警告:‘globalmem_write’ 定义后未使用
然后仔细想了原因,原来是在struct file_operations的赋值中没有将globalmem_write赋值给文件的结构体。
真是无语了,估计没人有这样的错误了。。。。。错误天才了哈哈
3. 最后一个问题是源程序的问题,出现如下错误:
hello
cat: /dev/globalmem: 没有那个设备或地址
在网上找了答案,globalmem _ read函数中的if (p >= GLOBALMEM _SIZE)改为if (p > GLOBALMEM _SIZE)
是一个指针的越界问题。

附1:depmod的解释

depmod(depend module) 信息来自"岁月联盟"

功能说明: 分析可载入模块的相依性。

语  法: depmod [-adeisvV][-m <文件>][--help][模块名称]

补充说明: depmod可检测模块的相依性,供modprobe在安装模块时使用。

参  数:
-a或--all  分析所有可用的模块。 
-d或debug  执行排错模式。 
-e  输出无法参照的符号。 
-i  不检查符号表的版本。 
-m<文件>或system-map<文件>  使用指定的符号表文件。 
-s或--system-log  在系统记录中记录错误。 
-v或--verbose  执行时显示详细的信息。 
-V或--version  显示版本信息。 
--help  显示帮助。


附2:
使用的makfile文件
ifneq ($(KERNELRELEASE),)
obj-m := globalmem.o

# Otherwise we were called directly from the command
# line; invoke the kernel build system.

else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)

default:
$(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) modules

endif

clean:
$(shell rm -f *.bak)
$(shell rm -f globalmem.o)
$(shell rm -f globalmem.ko)
$(shell rm -f globalmem.mod.c)
$(shell rm -f globalmem.mod.o)
$(shell rm -f Module.symvers)


附3:转自:(华清远见 http://www.embedu.org/index.htm)
内核中定义了struct class结构体,顾名思义,一个struct class结构体类型变量对应一个类,内核同时提供了class_create(…)函数,可以用它来创建一个类,这个类存放于sysfs下面,一旦创建 好了这个类,再调用device_create(…)函数来在/dev目录下创建相应的设备节点。这样,加载模块的时候,用户空间中的udev会自动响应 device_create(…)函数,去/sysfs下寻找对应的类从而创建设备节点。

  注意,在2.6较早的内核版本中,device_create(…)函数名称不同,是class_device_create(…),所以在新的内核中编译以前的模块程序有时会报错,就是因为函数名称不同,而且里面的参数设置也有一些变化。

  struct class和device_create(…) 以及device_create(…)都定义在/include/linux/device.h中,使用的时候一定要包含这个头文件,否则编译器会报错。

  在2.6.26.6内核版本中,struct class定义在头文件include/linux/device.h中:

  /*

  * device classes

  */

  struct class {

  const char        *name;

  struct module     *owner;

  nbsp;struct kset         subsys;

  struct list_head         devices;

  struct list_head         interfaces;

  struct kset              class_dirs;

  struct semaphore sem;    /* locks children, devices, interfaces */

  struct class_attribute   *class_attrs;

  struct device_attribute      *dev_attrs;

  int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);

  void (*class_release)(struct class *class);

  void (*dev_release)(struct device *dev);

  int (*suspend)(struct device *dev, pm_message_t state);

  int (*resume)(struct device *dev);

  };

  class_create(…)在/drivers/base/class.c中实现:

  /**

  * class_create - create a struct class structure

  * @owner: pointer to the module that is to "own" this struct class

  * @name: pointer to a string for the name of this class.

  *

  * This is used to create a struct class pointer that can then be used

  * in calls to device_create().

  *

  * Note, the pointer created here is to be destroyed when finished by

  * making a call to class_destroy().

  */

  struct class *class_create(struct module *owner, const char *name)

  {

  struct class *cls;

  int retval;

  cls = kzalloc(sizeof(*cls), GFP_KERNEL);

  if (!cls) {

  retval = -ENOMEM;

  goto error;

  }

  cls->name = name;

  cls->owner = owner;

  cls->class_release = class_create_release;

  retval = class_register(cls);

  if (retval)

  goto error;

  return cls;

  error:

  kfree(cls);

  return ERR_PTR(retval);

  }

  第一个参数指定类的所有者是哪个模块,第二个参数指定类名。

  在class.c中,还定义了class_destroy(…)函数,用于在模块卸载时删除类。

  device_create(…)函数在/drivers/base/core.c中实现:

  /**

  * device_create - creates a device and registers it with sysfs

  * @class: pointer to the struct class that this device should be registered to

  * @parent: pointer to the parent struct device of this new device, if any

  * @devt: the dev_t for the char device to be added

  * @fmt: string for the device's name

  *

  * This function can be used by char device classes. A struct device

  * will be created in sysfs, registered to the specified class.

  *

  * A "dev" file will be created, showing the dev_t for the device, if

  * the dev_t is not 0,0.

  * If a pointer to a parent struct device is passed in, the newly created

  * struct device will be a child of that device in sysfs.

  * The pointer to the struct device will be returned from the call.

  * Any further sysfs files that might be required can be created using this

  * pointer.

  *

  * Note: the struct class passed to this function must have previously

  * been created with a call to class_create().

  */

  struct device *device_create(struct class *class, struct device *parent,

  dev_t devt, const char *fmt, ...)

  {

  va_list vargs;

  struct device *dev;

  va_start(vargs, fmt);

  dev = device_create_vargs(class, parent, devt, NULL, fmt, vargs);

  va_end(vargs);

  return dev;

  }

  第一个参数指定所要创建的设备所从属的类,第二个参数是这个设备的父设备,如果没有就指定为NULL,第三个参数是设备号,第四个参数是设备名称,第五个参数是从设备号。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值