• OK6410 rmmod卸载模块失败:No such file or directory -- 转


     

    原文地址:http://hi.baidu.com/andio/item/b8be9810282841433a176e86

    rmmod chdir no such file or directory

    说明:

    1. 此文档基于 linux 2.6.32,TQ2440上测试通过,

    2. arm-linux-gcc版本 

    Thread model: posix
    gcc version 4.3.3 (Sourcery G++ Lite 2009q1-203)

    一. 问题描述及追踪分析

    使用 rmmod时候发现如下错误

    rmmod chdir no such file or directory

    追踪该错误信息,发现busybox rmmod.c   位置  busybox-1.xxx/modutils/rmmod.c

    函数框架如下

    int rmmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;

    int rmmod_main(int argc UNUSED_PARAM, char **argv)
    {
    //.......
        if (!*argv)
            bb_show_usage();

    //......

       while (*argv) {
            char modname[MODULE_NAME_LEN];
            const char *bname;

            bname = bb_basename(*argv++);
            if (n)
                safe_strncpy(modname, bname, MODULE_NAME_LEN);
            else
                filename2modname(bname, modname);
            if (bb_delete_module(modname, flags))
                bb_error_msg_and_die("can't unload '%s': %s",
                             modname, moderror(errno));
        }

        return EXIT_SUCCESS;
    }

    研究 这个函数,我们发现删除模块的 核心函数 是 bb_delete_module,追踪这个函数,在 /modutils/modutils.c中,我们得到如下函数

    int FAST_FUNC bb_delete_module(const char *module, unsigned int flags)
    {
        errno = 0;
        delete_module(module, flags);
        return errno;
    }
    这个表明rmmod实现是依靠 delete_module

    继续跟踪delete_module,

    #ifdef __UCLIBC__
    extern int delete_module(const char *module, unsigned int flags);
    #else
    # include <sys/syscall.h>
    # define delete_module(mod, flags) syscall(__NR_delete_module, mod, flags)
    #endif

    这个 是什么意思呢?

    如果定义了 __UCLIBC__  则使用uClibc中的  delete_module(const char *module, unsigned int flags)函数

    否则,则用系统调用内核的 sys_delete_module函数 该函数原型如下

    asmlinkage long sys_delete_module(const char __user *  name_user,  unsigned int  flags);     

    我们 再来看 safe_strncpy(modname, bname, MODULE_NAME_LEN); 函数和 filename2modname(bname, modname);函数

    这俩个函数 的作用都是获得 模块名称 ,使用的核心实现方式是  strrchr(name, '/');

    char *strchr(const char *s, int c);
    The strrchr() function returns a pointer to the last occurrence of  the character c in the string s.

    这个意思时说strrchr函数返回字符C在 字符串S中最后一次出现的位置。

    假如我们使用如下指令

    #rmmod  /lib/modules/2.6.32/adc.ko

    经过函数处理后, modname 将变回 adc.ko

    值得注意的是 bb_basename() 函数如下

    const char* FAST_FUNC bb_basename(const char *name)
    {
        const char *cp = strrchr(name, '/');
        if (cp)
            return cp + 1;
        return name;
    } 该函数 已经进行了一次处理

    另外, filename2modname 函数

    char * FAST_FUNC filename2modname(const char *filename, char *modname)
    {
        int i;
        char *from;
     if (filename == NULL)
            return NULL;
        if (modname == NULL)
            modname = xmalloc(MODULE_NAME_LEN);
        from = bb_get_last_path_component_nostrip(filename);
        for (i = 0; i < (MODULE_NAME_LEN-1) && from[i] != '' &&from[i] != '.'; i++)
            modname[i] = (from[i] == '-') ? '_' : from[i];
        modname[i] = '';

        return modname;
    }

    注意

     from[i] != '.' ,这个意味着 adc.ko 会被解析成adc

    from[i] == '-'? '_' : from[i]这个意味着 adc-xyz会被解析成adc_xyz

    分析到这里,我们也就知道了rmmod的全过程,核心在于利用sys_delete_module函数卸载驱动模块

    下面给出解决方法

    二. 解决方法

     建立rmmod.c ,内容如下

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <string.h>
    #include <errno.h>
    int main(int argc, char *argv[])
    {
    int ret = -1;
    int left_time =5;
    int i=0;
    if(!argv[1])
    {
        printf("usage: rmmod modename ");
        return -1;

    }

    char *modname = argv[1];

    while(argv[1][i]!='')

    {

    //如下这个 是为了 rmmod adc.ko 与 rmmod adc效果一致

    if(argv[1][i]=='.'){argv[1][i]='';break;}
    i++;
    };

    while (left_time-- > 0) {
    ret = delete_module(modname, O_NONBLOCK | O_EXCL);//系统调用sys_delete_module
    if (ret < 0 && errno == EAGAIN)
    sleep(1);
    else
    break;
    }
    if (ret != 0) printf("Error when rmmod module %s: %s ",modname, strerror(errno));
    return 0;

    }

    在PC中

    #arm-linux-gcc rmmod.c -o rmmod

    在板子中

    #mv /sbin/rmmod /sbin/rmmod2

    #mv rmmod /sbin/rmmod 

  • 相关阅读:
    如何降低客户流失率高的问题
    移动端时代如何进行营销革命
    EDM备忘录:触发式邮件订阅和退订功能介绍
    EDM博主笔记:EDM邮件营销的几个细节问题
    转载好文:如何进行基于情境数据的个性化EDM数据营销
    个性化EDM数据营销的三大提醒
    许可EDM营销是个长期过程
    内容营销三大实用法则(内含干货)-同样可运用在EDM数据营销中
    改善EDM数据营销的关键点
    《FS Book》: 如何让圣诞节邮件营销与众不同
  • 原文地址:https://www.cnblogs.com/chenchenluo/p/3256144.html
Copyright © 2020-2023  润新知