亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 5714 | 回復: 8
打印 上一主題 下一主題

模塊的符號導出后其他模塊不能調用求解 [復制鏈接]

論壇徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:50:28
跳轉到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2009-04-29 21:36 |只看該作者 |倒序瀏覽
5可用積分
其實就是LDD的例子,其中作者自己實現(xiàn)了一個簡單的總線 ldd_bus 代碼如下:
ldd_bus.h

MODULE_LICENSE("GPL");
extern struct bus_type ldd_bus_type;
/*
 * The LDD driver type.
 */

struct ldd_driver {
    char *version;
    struct module *module;
    struct device_driver driver;
    struct driver_attribute version_attr;
};

#define to_ldd_driver(drv) container_of(drv, struct ldd_driver, driver);

/*
 * A device type for things "plugged" into the LDD bus.
 */


struct ldd_device {
    char *name;
    struct ldd_driver *driver;
    struct device dev;
};

#define to_ldd_device(dev) container_of(dev, struct ldd_device, dev);

extern int register_ldd_device(struct ldd_device *);
extern void unregister_ldd_device(struct ldd_device *);
extern int register_ldd_driver(struct ldd_driver *);
extern void unregister_ldd_driver(struct ldd_driver *);
ldd_bus.c

#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>
#include "lddbus.h"

MODULE_AUTHOR("Jonathan Corbet");
MODULE_LICENSE("GPL");
static char *Version = "$Revision: 1.9 $";

/*
 * Respond to hotplug events.
 */

//static int ldd_hotplug(struct device *dev, char **envp, int num_envp,

//        char *buffer, int buffer_size)

static int ldd_uevent(struct device *dev, struct kobj_uevent_env *env)
{
    struct ldd_device *pdev;

    if (!dev)
        return -ENODEV;
    
    pdev = to_ldd_device(dev);
    
    if (!pdev)
        return -ENODEV;
    
    if (add_uevent_var(env, "LDDBUS_VERSION=%s", Version))
        return -ENOMEM;    
    /*    
    envp[0] = buffer;
    if (snprintf(buffer, buffer_size, "LDDBUS_VERSION=%s",
                Version) >= buffer_size)
        return -ENOMEM;
    envp[1] = NULL;
    */

    
    return 0;
}

/*
 * Match LDD devices to drivers.  Just do a simple name test.
 */

static int ldd_match(struct device *dev, struct device_driver *driver)
{
    return !strncmp(dev->bus_id, driver->name, strlen(driver->name));
}


/*
 * The LDD bus device.
 */

static void ldd_bus_release(struct device *dev)
{
    printk(KERN_DEBUG "lddbus release\n");
}
    
struct device ldd_bus = {
    .bus_id   = "ldd0",
    .release  = ldd_bus_release
};


/*
 * And the bus type.
 */

struct bus_type ldd_bus_type = {
    .name = "ldd",
    .match = ldd_match,
    //.hotplug  = ldd_hotplug,

    .uevent = ldd_uevent,
};

/*
 * Export a simple attribute.
 */

static ssize_t show_bus_version(struct bus_type *bus, char *buf)
{
    return snprintf(buf, PAGE_SIZE, "%s\n", Version);
}

static BUS_ATTR(version, S_IRUGO, show_bus_version, NULL);



/*
 * LDD devices.
 */


/*
 * For now, no references to LDDbus devices go out which are not
 * tracked via the module reference count, so we use a no-op
 * release function.
 */

static void ldd_dev_release(struct device *dev)
{ }

int register_ldd_device(struct ldd_device *ldddev)
{
    ldddev->dev.bus = &ldd_bus_type;
    ldddev->dev.parent = &ldd_bus;
    ldddev->dev.release = ldd_dev_release;
    strncpy(ldddev->dev.bus_id, ldddev->name, BUS_ID_SIZE);
    return device_register(&ldddev->dev);
}
EXPORT_SYMBOL(register_ldd_device);

void unregister_ldd_device(struct ldd_device *ldddev)
{
    device_unregister(&ldddev->dev);
}
EXPORT_SYMBOL(unregister_ldd_device);
int sculld_init(void)
{
&nbsp;&nbsp;&nbsp;&nbsp;int result, i;
&nbsp;&nbsp;&nbsp;&nbsp;dev_t dev = MKDEV(sculld_major, 0);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;/*
&nbsp;&nbsp;&nbsp;&nbsp; * Register your major, and accept a dynamic number.
&nbsp;&nbsp;&nbsp;&nbsp; */

&nbsp;&nbsp;&nbsp;&nbsp;if (sculld_major)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result = register_chrdev_region(dev, sculld_devs, "sculld");
&nbsp;&nbsp;&nbsp;&nbsp;else {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result = alloc_chrdev_region(&dev, 0, sculld_devs, "sculld");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sculld_major = MAJOR(dev);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;if (result < 0)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return result;

&nbsp;&nbsp;&nbsp;&nbsp;/*
&nbsp;&nbsp;&nbsp;&nbsp; * Register with the driver core.
&nbsp;&nbsp;&nbsp;&nbsp; */

&nbsp;&nbsp;&nbsp;&nbsp;register_ldd_driver(&sculld_driver);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;/*
&nbsp;&nbsp;&nbsp;&nbsp; * allocate the devices -- we can't have them static, as the number
&nbsp;&nbsp;&nbsp;&nbsp; * can be specified at load time
&nbsp;&nbsp;&nbsp;&nbsp; */

&nbsp;&nbsp;&nbsp;&nbsp;sculld_devices = kmalloc(sculld_devs*sizeof (struct sculld_dev), GFP_KERNEL);
&nbsp;&nbsp;&nbsp;&nbsp;if (!sculld_devices) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result = -ENOMEM;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;goto fail_malloc;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;memset(sculld_devices, 0, sculld_devs*sizeof (struct sculld_dev));
&nbsp;&nbsp;&nbsp;&nbsp;for (i = 0; i < sculld_devs; i++) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sculld_devices[i].order = sculld_order;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sculld_devices[i].qset = sculld_qset;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sema_init (&sculld_devices[i].sem, 1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sculld_setup_cdev(sculld_devices + i, i);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sculld_register_dev(sculld_devices + i, i);
&nbsp;&nbsp;&nbsp;&nbsp;}


//#ifdef SCULLD_USE_PROC /* only when available */

&nbsp;&nbsp;&nbsp;&nbsp;create_proc_read_entry("sculldmem", 0, NULL, sculld_read_procmem, NULL);
//#endif

&nbsp;&nbsp;&nbsp;&nbsp;return 0; /* succeed */

&nbsp;&nbsp;fail_malloc:
&nbsp;&nbsp;&nbsp;&nbsp;unregister_chrdev_region(dev, sculld_devs);
&nbsp;&nbsp;&nbsp;&nbsp;return result;
}

在另一個模塊里調用EXPORT的函數,編譯的時候 WARNING: "register_ldd_driver" [/sculld/sculld.ko] undefined! insmod 的時候出錯 Unknown symbol in module

cat /proc/kallsyms | grep register_ldd_driver
ffffffffa0493310 r __ksymtab_unregister_ldd_driver        [lddbus]
ffffffffa0493370 r __kstrtab_unregister_ldd_driver        [lddbus]
ffffffffa0493350 r __kcrctab_unregister_ldd_driver        [lddbus]
ffffffffa0493320 r __ksymtab_register_ldd_driver        [lddbus]
ffffffffa0493386 r __kstrtab_register_ldd_driver        [lddbus]
ffffffffa0493358 r __kcrctab_register_ldd_driver        [lddbus]
ffffffffa0493330 r __ksymtab_unregister_ldd_device        [lddbus]
ffffffffa049339a r __kstrtab_unregister_ldd_device        [lddbus]
ffffffffa0493360 r __kcrctab_unregister_ldd_device        [lddbus]
ffffffffa0493130 t unregister_ldd_driver        [lddbus]
00000000cea62aa1 a __crc_unregister_ldd_device        [lddbus]
00000000750790d6 a __crc_register_ldd_device        [lddbus]
ffffffffa04931f0 t register_ldd_device        [lddbus]
0000000073ce301d a __crc_unregister_ldd_driver        [lddbus]
ffffffffa04930d0 t unregister_ldd_device        [lddbus]
000000002db493e5 a __crc_register_ldd_driver        [lddbus]
ffffffffa0493140 t register_ldd_driver        [lddbus]


[ 本帖最后由 www1862 于 2009-4-29 21:45 編輯 ]

論壇徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辭舊歲徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
2 [報告]
發(fā)表于 2009-04-29 21:59 |只看該作者

回復 #1 www1862 的帖子

前面有個哥們說,符號表里面要是類型u的才能被調用

論壇徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:50:28
3 [報告]
發(fā)表于 2009-04-29 22:02 |只看該作者

回復 #2 dreamice 的帖子

你的問題解決了嗎?不是已經用EXPORT_SYMBOL(fun) 導出了嗎?為什么還不能用?

論壇徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:50:28
4 [報告]
發(fā)表于 2009-04-29 23:12 |只看該作者
看了一下,ssb b43 的代碼,發(fā)現(xiàn)沒什么不一樣,不過SSB B43都在內核樹里。關于2樓的說法,我的理解是U 是調用者 USE的意思,因為b43 依賴ssb模塊,且ssb_device_enable 是ssb模塊里的 函數。
cat /proc/kallsyms | grep ssb_device_enable
ffffffffa0033310 u ssb_device_enable        [b43]
ffffffffa0037c60 r __ksymtab_ssb_device_enable        [ssb]
ffffffffa0037e79 r __kstrtab_ssb_device_enable        [ssb]
ffffffffa0037d68 r __kcrctab_ssb_device_enable        [ssb]
ffffffffa0033310 T ssb_device_enable        [ssb]
00000000654ba824 a __crc_ssb_device_enable        [ssb]


[ 本帖最后由 www1862 于 2009-4-29 23:13 編輯 ]

論壇徽章:
0
5 [報告]
發(fā)表于 2009-04-29 23:36 |只看該作者
.H文件里:
extern int register_ldd_device(struct ldd_device *);
extern void unregister_ldd_device(struct ldd_device *);
extern int register_ldd_driver(struct ldd_driver *);
extern void unregister_ldd_driver(struct ldd_driver *);

上面前2行和后面2行一樣的。苛硗,EXTERN似乎可以去掉吧?因為在.C里面實現(xiàn)了啊。又不是在其他地方實現(xiàn)的。

還有,你調用 register_ldd_driver 的模塊是怎么寫的? 應該加了 extern int register_ldd_driver(struct ldd_driver *); 這句吧?

論壇徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:50:28
6 [報告]
發(fā)表于 2009-04-30 00:54 |只看該作者

回復 #5 accessory 的帖子

不一樣,一個是device 一個是driver。
解決了,原來是lddbus.c 頭文件的引用問題。

[ 本帖最后由 www1862 于 2009-4-30 16:43 編輯 ]

論壇徽章:
0
7 [報告]
發(fā)表于 2009-04-30 22:58 |只看該作者
不錯,學習了。

論壇徽章:
0
8 [報告]
發(fā)表于 2010-12-03 14:53 |只看該作者
回復 1# www1862


    樓主能再具體說下怎么解決的嗎? 我看lddbus.c頭文件的引用 找不到問題?

論壇徽章:
0
9 [報告]
發(fā)表于 2011-02-12 17:21 |只看該作者
u的意思是undefined吧
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復

  

北京盛拓優(yōu)訊信息技術有限公司. 版權所有 京ICP備16024965號-6 北京市公安局海淀分局網監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關心和支持過ChinaUnix的朋友們 轉載本站內容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP