精华内容
下载资源
问答
  • linux电脑访问android手机存储

    千次阅读 2017-12-01 19:59:12
    linux电脑访问android手机存储 Linux 电脑安装jmtpfs:apt-get install jmtpfs 安装后,/dev 目录下有libmtp-1-2 文件,版本不一样也可以是 libmtp-x-x。 挂载文件系统:jmtpfs /xxxxx (/xxxxx 自己想写啥写啥) 访问...

    系统软件确认:

    手机:android 系统

    电脑:linux 系统

    (测试手机 android7.1.2,电脑 debian9.2,其他没测试过)

     

    手机端设置:

    手机usb线连接电脑,usb 使用方式:

    1,如果有 usb 大容量存储器选项,以 usb 大容量存储器形式读写,和直接读写u盘一样,不说

    2,如果没有usb 大容量存储器选项,大多有三个选项,1充电,2传输文件,3ptp

    选2就是mtp连接方式:

     

    电脑端设置:

    Linux 电脑安装jmtpfs:apt-get install jmtpfs

    安装后,/dev 目录下有libmtp-1-2 文件,版本不一样也可以是 libmtp-x-x。

    挂载文件系统:jmtpfs  /xxxxx  (/xxxxx 自己想写啥写啥)

    访问文件系统:cd /xxxx,就看到这个

    cd 内部共享存储空间;  ls  就看到手机存储根目录:


    展开全文
  • Linux配置Android设备USB访问权限

    千次阅读 2017-12-14 09:19:03
    附USB 供应商 ID列表参考Android Studio用户指南——在硬件设备上运行应用 手机开启调试调试模式,连接电脑,运行adb devices,如果没有usb设备访问权限,此时会显示:$ adb devices List of devices attached 01bf...

    参考

    Android Studio用户指南——在硬件设备上运行应用
    手机开启调试模式,连接电脑,执行adb devices命令,如果没有usb设备访问权限,此时会显示:

    $ adb devices
    List of devices attached
    01bf27deae6532f8        no permissions; see [http://developer.android.com/tools/device.html]

    查看USB设备ID

    通过lsusb命令查看USB设备ID:

    $ lsusb
    Bus 001 Device 073: ID 18d1:4ee7 Google Inc. 
    Bus 001 Device 002: ID 046d:c31d Logitech, Inc. Media Keyboard K200
    Bus 001 Device 003: ID 046d:c05a Logitech, Inc. M90/M100 Optical Mouse
    Bus 003 Device 002: ID 8087:8008 Intel Corp. 
    Bus 004 Device 002: ID 8087:8000 Intel Corp. 
    Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
    Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    Bus 004 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

    我这里使用的是Google Nexus 5X手机,结合参考页面的USB 供应商 ID表和命令结果的描述可以确定,我的手机的USB设备ID是18d1:4ee7。

    配置USB访问权限

    以root权限创建文件:/etc/udev/rules.d/51-android.rules,按如下格式添加内容:

    SUBSYSTEM=="usb", ATTR{idVendor}=="0bb4", MODE="0666", GROUP="plugdev" 

    所以,我这里需要对应的添加一行Google的USB 供应商 ID:

    SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", MODE="0666", GROUP="plugdev" 

    然后设置文件可读:

    $ chmod a+r /etc/udev/rules.d/51-android.rules

    此时重新插拔一下手机,再次运行adb devices查看

    $ adb devices
    List of devices attached
    01bf27deae6532f8        unauthorized

    状态是未授权,这时手机屏幕上应该就出现了确认允许这台电脑进行调试的对话框,确认授权后,就可以连接到手机了。

    $ adb devices
    List of devices attached
    01bf27deae6532f8        device
    
    $ adb shell
    bullhead:/ $ 

    附:USB 供应商 ID列表

    公司 USB 供应商 ID
    Acer 0502
    ASUS 0b05
    Dell 413c
    Foxconn 0489
    Fujitsu 04c5
    Fujitsu Toshiba 04c5
    Garmin-Asus 091e
    Google 18d1
    Haier 201E
    Hisense 109b
    HP 03f0
    HTC 0bb4
    Huawei 12d1
    Intel 8087
    K-Touch 24e3
    KT Tech 2116
    Kyocera 0482
    Lenovo 17ef
    LG 1004
    Motorola 22b8
    MTK 0e8d
    NEC 0409
    Nook 2080
    Nvidia 0955
    OTGV 2257
    Pantech 10a9
    Pegatron 1d4d
    Philips 0471
    PMC-Sierra 04da
    Qualcomm 05c6
    SK Telesys 1f53
    Samsung 04e8
    Sharp 04dd
    Sony 054c
    Sony Ericsson 0fce
    Sony Mobile Communications 0fce
    Teleepoch 2340
    Toshiba 0930
    ZTE 19d2
    展开全文
  • android HAL访问linux内核驱动

    千次阅读 2012-04-08 18:16:58
    Android硬件抽象层(HAL)概要介绍和学习计划...接着,在Ubuntu上为Android系统编写Linux内核驱动程序一文中举例子说明了如何在Linux内核编写驱动程序。在这一篇文章中,我们将继续介绍Android系统硬件驱动程序的另一
       在Android硬件抽象层(HAL)概要介绍和学习计划一文中,我们简要介绍了在Android系统为为硬件编写驱动程序的方法。简单来说,硬件驱动程序一方面分布在Linux内核中,另一方面分布在用户空间的硬件抽象层中。接着,在Ubuntu上为Android系统编写Linux内核驱动程序一文中举例子说明了如何在Linux内核编写驱动程序。在这一篇文章中,我们将继续介绍Android系统硬件驱动程序的另一方面实现,即如何在硬件抽象层中增加硬件模块来和内核驱动程序交互。在这篇文章中,我们还将学习到如何在Android系统创建设备文件时用类似Linux的udev规则修改设备文件模式的方法。
    

          一. 参照在Ubuntu上为Android系统编写Linux内核驱动程序一文所示,准备好示例内核驱动序。完成这个内核驱动程序后,便可以在Android系统中得到三个文件,分别是/dev/hello、/sys/class/hello/hello/val和/proc/hello。在本文中,我们将通过设备文件/dev/hello来连接硬件抽象层模块和Linux内核驱动程序模块。

          二. 进入到在hardware/libhardware/include/hardware目录,新建hello.h文件:

          USER-NAME@MACHINE-NAME:~/Android$ cd hardware/libhardware/include/hardware

          USER-NAME@MACHINE-NAME:~/Android/hardware/libhardware/include/hardware$ vi hello.h

          hello.h文件的内容如下:

          

    1. #ifndef ANDROID_HELLO_INTERFACE_H   
    2. #define ANDROID_HELLO_INTERFACE_H   
    3. #include <hardware/hardware.h>   
    4.   
    5. __BEGIN_DECLS  
    6.   
    7. /*定义模块ID*/  
    8. #define HELLO_HARDWARE_MODULE_ID "hello"   
    9.   
    10. /*硬件模块结构体*/  
    11. struct hello_module_t {  
    12.     struct hw_module_t common;  
    13. };  
    14.   
    15. /*硬件接口结构体*/  
    16. struct hello_device_t {  
    17.     struct hw_device_t common;  
    18.     int fd;  
    19.     int (*set_val)(struct hello_device_t* dev, int val);  
    20.     int (*get_val)(struct hello_device_t* dev, int* val);  
    21. };  
    22.   
    23. __END_DECLS  
    24.   
    25. #endif  

          这里按照Android硬件抽象层规范的要求,分别定义模块ID、模块结构体以及硬件接口结构体。在硬件接口结构体中,fd表示设备文件描述符,对应我们将要处理的设备文件"/dev/hello",set_val和get_val为该HAL对上提供的函数接口。

          三. 进入到hardware/libhardware/modules目录,新建hello目录,并添加hello.c文件。 hello.c的内容较多,我们分段来看。

          首先是包含相关头文件和定义相关结构:

          

    1. #define LOG_TAG "HelloStub"   
    2.   
    3. #include <hardware/hardware.h>   
    4. #include <hardware/hello.h>   
    5. #include <fcntl.h>   
    6. #include <errno.h>   
    7. #include <cutils/log.h>   
    8. #include <cutils/atomic.h>   
    9.   
    10. #define DEVICE_NAME "/dev/hello"   
    11. #define MODULE_NAME "Hello"   
    12. #define MODULE_AUTHOR "shyluo@gmail.com"   
    13.   
    14. /*设备打开和关闭接口*/  
    15. static int hello_device_open(const struct hw_module_t* module, const char* name, struct hw_device_t** device);  
    16. static int hello_device_close(struct hw_device_t* device);  
    17.   
    18. /*设备访问接口*/  
    19. static int hello_set_val(struct hello_device_t* dev, int val);  
    20. static int hello_get_val(struct hello_device_t* dev, int* val);  
    21.   
    22. /*模块方法表*/  
    23. static struct hw_module_methods_t hello_module_methods = {  
    24.     open: hello_device_open  
    25. };  
    26.   
    27. /*模块实例变量*/  
    28. struct hello_module_t HAL_MODULE_INFO_SYM = {  
    29.     common: {  
    30.         tag: HARDWARE_MODULE_TAG,  
    31.         version_major: 1,  
    32.         version_minor: 0,  
    33.         id: HELLO_HARDWARE_MODULE_ID,  
    34.         name: MODULE_NAME,  
    35.         author: MODULE_AUTHOR,  
    36.         methods: &hello_module_methods,  
    37.     }  
    38. };  

          这里,实例变量名必须为HAL_MODULE_INFO_SYM,tag也必须为HARDWARE_MODULE_TAG,这是Android硬件抽象层规范规定的。

          定义hello_device_open函数:

          

    1. static int hello_device_open(const struct hw_module_t* module, const char* name, struct hw_device_t** device) {  
    2.     struct hello_device_t* dev;dev = (struct hello_device_t*)malloc(sizeof(struct hello_device_t));  
    3.       
    4.     if(!dev) {  
    5.         LOGE("Hello Stub: failed to alloc space");  
    6.         return -EFAULT;  
    7.     }  
    8.   
    9.     memset(dev, 0, sizeof(struct hello_device_t));  
    10.     dev->common.tag = HARDWARE_DEVICE_TAG;  
    11.     dev->common.version = 0;  
    12.     dev->common.module = (hw_module_t*)module;  
    13.     dev->common.close = hello_device_close;  
    14.     dev->set_val = hello_set_val;dev->get_val = hello_get_val;  
    15.   
    16.     if((dev->fd = open(DEVICE_NAME, O_RDWR)) == -1) {  
    17.         LOGE("Hello Stub: failed to open /dev/hello -- %s.", strerror(errno));free(dev);  
    18.         return -EFAULT;  
    19.     }  
    20.   
    21.     *device = &(dev->common);  
    22.     LOGI("Hello Stub: open /dev/hello successfully.");  
    23.   
    24.     return 0;  
    25. }  

          DEVICE_NAME定义为"/dev/hello"。由于设备文件是在内核驱动里面通过device_create创建的,而device_create创建的设备文件默认只有root用户可读写,而hello_device_open一般是由上层APP来调用的,这些APP一般不具有root权限,这时候就导致打开设备文件失败:

          Hello Stub: failed to open /dev/hello -- Permission denied.
          解决办法是类似于Linux的udev规则,打开Android源代码工程目录下,进入到system/core/rootdir目录,里面有一个名为ueventd.rc文件,往里面添加一行:
          /dev/hello 0666 root root
          定义hello_device_close、hello_set_val和hello_get_val这三个函数:
          
    1. static int hello_device_close(struct hw_device_t* device) {  
    2.     struct hello_device_t* hello_device = (struct hello_device_t*)device;  
    3.   
    4.     if(hello_device) {  
    5.         close(hello_device->fd);  
    6.         free(hello_device);  
    7.     }  
    8.       
    9.     return 0;  
    10. }  
    11.   
    12. static int hello_set_val(struct hello_device_t* dev, int val) {  
    13.     LOGI("Hello Stub: set value %d to device.", val);  
    14.   
    15.     write(dev->fd, &val, sizeof(val));  
    16.   
    17.     return 0;  
    18. }  
    19.   
    20. static int hello_get_val(struct hello_device_t* dev, int* val) {  
    21.     if(!val) {  
    22.         LOGE("Hello Stub: error val pointer");  
    23.         return -EFAULT;  
    24.     }  
    25.   
    26.     read(dev->fd, val, sizeof(*val));  
    27.   
    28.     LOGI("Hello Stub: get value %d from device", *val);  
    29.   
    30.     return 0;  
    31. }  

          四. 继续在hello目录下新建Android.mk文件:
          LOCAL_PATH := $(call my-dir)
          include $(CLEAR_VARS)
          LOCAL_MODULE_TAGS := optional
          LOCAL_PRELINK_MODULE := false
          LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
          LOCAL_SHARED_LIBRARIES := liblog
          LOCAL_SRC_FILES := hello.c
          LOCAL_MODULE := hello.default
          include $(BUILD_SHARED_LIBRARY)
          注意,LOCAL_MODULE的定义规则,hello后面跟有default,hello.default能够保证我们的模块总能被硬象抽象层加载到。
          五. 编译:
          USER-NAME@MACHINE-NAME:~/Android$ mmm hardware/libhardware/modules/hello
          编译成功后,就可以在out/target/product/generic/system/lib/hw目录下看到hello.default.so文件了。
          六. 重新打包Android系统镜像system.img:
          USER-NAME@MACHINE-NAME:~/Android$ make snod
          重新打包后,system.img就包含我们定义的硬件抽象层模块hello.default了。
          虽然我们在Android系统为我们自己的硬件增加了一个硬件抽象层模块,但是现在Java应用程序还不能访问到我们的硬件。我们还必须编写JNI方法和在Android的Application Frameworks层增加API接口,才能让上层Application访问我们的硬件。在接下来的文章中,我们还将完成这一系统过程,使得我们能够在Java应用程序中访问我们自己定制的硬件。
    展开全文
  • 一直都想亲自做一次使用android应用程序访问Linux内核驱动的尝试,但总是没能做到。最近抽出时间,下决心重新尝试一次。尝试的开始当然是先写一个Linux内核驱动了。 我希望写一个简单测驱动程序,实现写一个字符串...

    一直都想亲自做一次使用android应用程序访问Linux内核驱动的尝试,但总是没能做到。最近抽出时间,下决心重新尝试一次。尝试的开始当然是先写一个Linux内核驱动了。
    我希望写一个简单测驱动程序,实现写一个字符串进去,然后再把它读出来的功能。驱动中会创建dev/hello设备节点和/sys/class/hello/hello/val 设备节点,没有实现proc/下的对应的设备节点。/sys/class/hello/hello/val 主要用于快速测试,而dev/hello则主要用于供上层应用调用。
    这篇博客参考了老罗的android之旅相关博客:http://blog.csdn.net/luoshengyang/article/details/6568411

    一。驱动源码

    代码我已经在android6.0的linux kernel上测试过了,代码中有响应的注释,所以这里直接贴出代码:

    hello.c

    文件如下:

    #include <linux/init.h>  
    #include <linux/module.h>  
    #include <linux/types.h>  
    #include <linux/fs.h>  
    #include <linux/proc_fs.h>  
    #include <linux/device.h>  
    
    #include <linux/sched.h>
    #include <linux/errno.h>
    #include <linux/fcntl.h>
    
    #include <linux/poll.h>
    #include <linux/seq_file.h>
    #include <linux/mutex.h>
    #include <linux/workqueue.h>
    
    #include <asm/uaccess.h>
    #include <linux/slab.h>
    
    
    #include "hello.h"  
    
    /*定义主设备和从设备号变量*/  
    static int hello_major = 0;  
    static int hello_minor = 0;  
    
    /*设备类别和设备变量*/  
    static struct class* hello_class = NULL;  
    static struct hello_test_dev* hello_dev = NULL;  
    
    /*传统的设备文件操作方法*/  
    static int hello_open(struct inode* inode, struct file* filp);  
    static int hello_release(struct inode* inode, struct file* filp);  
    static ssize_t hello_read(struct file* filp, char __user *buf, size_t count, loff_t* f_pos);  
    static ssize_t hello_write(struct file* filp, const char __user *buf, size_t count, loff_t* f_pos);  
    
    /*设备文件操作方法表*/  
    static struct file_operations hello_fops = {  
        .owner = THIS_MODULE,  
        .open = hello_open,  
        .release = hello_release,  
        .read = hello_read,  
        .write = hello_write,   
    };  
    
    /*访问设置属性方法*/  
    static ssize_t hello_val_show(struct device* dev, struct device_attribute* attr,  char* buf);  
    static ssize_t hello_val_store(struct device* dev, struct device_attribute* attr, const char* buf, size_t count);  
    
    /*定义设备属性*/  
    static DEVICE_ATTR(val, S_IRUGO | S_IWUSR, hello_val_show, hello_val_store); 
    
    /*打开设备方法*/  
    static int hello_open(struct inode* inode, struct file* filp) {  
        struct hello_test_dev* dev;          
    
        /*将自定义设备结构体保存在文件指针的私有数据域中,以便访问设备时拿来用*/  
        dev = container_of(inode->i_cdev, struct hello_test_dev, dev);  
        filp->private_data = dev;  
    
        return 0;  
    }  
    
    /*设备文件释放时调用,空实现*/  
    static int hello_release(struct inode* inode, struct file* filp) {  
        return 0;  
    }  
    
    /*读内存*/  
    static ssize_t hello_read(struct file* filp, char __user *buf, size_t count, loff_t* f_pos) {  
        ssize_t err = 0;  
        struct hello_test_dev* dev = filp->private_data;          
    
        /*同步访问*/  
        if(down_interruptible(&(dev->sem))) {  
            return -ERESTARTSYS;  
        }  
    
        if(count < sizeof(dev->val)) {  
            goto out;  
        }          
    
        /*读字符串*/  
        if(copy_to_user(buf, dev->val, sizeof(dev->val))) {  
            err = -EFAULT;  
            goto out;  
        }  
    
        err = sizeof(dev->val);  
    
    out:  
        up(&(dev->sem));  
        return err;  
    }  
    
    /*写字符串*/  
    static ssize_t hello_write(struct file* filp, const char __user *buf, size_t count, loff_t* f_pos) {  
        struct hello_test_dev* dev = filp->private_data;  
        ssize_t err = 0;          
    
        /*同步访问*/  
        if(down_interruptible(&(dev->sem))) {  
            return -ERESTARTSYS;          
        }          
    
        if(count != sizeof(dev->val)) {  
            goto out;          
        }          
    
        /*将用户写进来的字符串保存到驱动的内存中*/  
        if(copy_from_user(dev->val, buf, count)) {  
            err = -EFAULT;  
            goto out;  
        }  
    
        err = sizeof(dev->val);  
    
    out:  
        up(&(dev->sem));  
        return err;  
    }  
    
    
    /*写字符串到内存*/  
    static ssize_t __hello_set_val(struct hello_test_dev* dev, const char* buf, size_t count) {       
    
        /*同步访问*/          
        if(down_interruptible(&(dev->sem))) {                  
            return -ERESTARTSYS;          
        }          
        printk(KERN_ALERT"__hello_set_val.buf: %s  count:%d\n",buf,count);
        printk(KERN_ALERT"__hello_set_val.dev->val: %s  count:%d\n",dev->val,count);
        strncpy(dev->val,buf, count);
        printk(KERN_ALERT"__hello_set_val.dev->val: %s  count:%d\n",dev->val,count);
        up(&(dev->sem));  
    
        return count;  
    }  
    
    /*读取设备属性val*/  
    static ssize_t hello_val_show(struct device* dev, struct device_attribute* attr, char* buf) {  
        struct hello_test_dev* hdev = (struct hello_test_dev*)dev_get_drvdata(dev);          
        printk(KERN_ALERT"hello_val_show.\n");
        printk(KERN_ALERT"%s\n",hdev->val);
        return 0;
    }  
    
    /*写设备属性val*/  
    static ssize_t hello_val_store(struct device* dev, struct device_attribute* attr, const char* buf, size_t count) {   
        struct hello_test_dev* hdev = (struct hello_test_dev*)dev_get_drvdata(dev);    
        printk(KERN_ALERT"hello_val_store.buf: %s  count:%d\n",buf,count);
    
        return __hello_set_val(hdev, buf, count);  
    }  
    
    
    /*初始化设备*/  
    static int  __hello_setup_dev(struct hello_test_dev* dev) {  
        int err;  
        dev_t devno = MKDEV(hello_major, hello_minor);  
    
        memset(dev, 0, sizeof(struct hello_test_dev));  
    
        cdev_init(&(dev->dev), &hello_fops);  
        dev->dev.owner = THIS_MODULE;  
        dev->dev.ops = &hello_fops;          
    
        /*注册字符设备*/  
        err = cdev_add(&(dev->dev),devno, 1);  
        if(err) {  
            return err;  
        }          
    
        /*初始化信号量和寄存器val的值*/  
        init_MUTEX(&(dev->sem));  
        dev->val = kmalloc(10,GFP_KERNEL);  
        strncpy(dev->val,"hello",sizeof("hello"));
        return 0;  
    }  
    
    /*模块加载方法*/  
    static int __init hello_init(void){   
        int err = -1;  
        dev_t dev = 0;  
        struct device* temp = NULL;  
    
        printk(KERN_ALERT"hello_init.\n");          
    
        /*动态分配主设备和从设备号*/  
        err = alloc_chrdev_region(&dev, 0, 1, HELLO_DEVICE_NODE_NAME);  
        if(err < 0) {  
            printk(KERN_ALERT"Failed to alloc char dev region.\n");  
            goto fail;  
        }  
    
        hello_major = MAJOR(dev);  
        hello_minor = MINOR(dev);          
    
        /*分配helo设备结构体变量*/  
        hello_dev = kmalloc(sizeof(struct hello_test_dev), GFP_KERNEL);  
        if(!hello_dev) {  
            err = -ENOMEM;  
            printk(KERN_ALERT"Failed to alloc hello_dev.\n");  
            goto unregister;  
        }          
    
        /*初始化设备*/  
        err = __hello_setup_dev(hello_dev);  
        if(err) {  
            printk(KERN_ALERT"Failed to setup dev: %d.\n", err);  
            goto cleanup;  
        }          
    
        /*在/sys/class/目录下创建设备类别目录hello*/  
        hello_class = class_create(THIS_MODULE, HELLO_DEVICE_CLASS_NAME);  
        if(IS_ERR(hello_class)) {  
            err = PTR_ERR(hello_class);  
            printk(KERN_ALERT"Failed to create hello class.\n");  
            goto destroy_cdev;  
        }          
    
        /*在/dev/目录和/sys/class/hello目录下分别创建设备文件hello*/  
        temp = device_create(hello_class, NULL, dev, "%s", HELLO_DEVICE_FILE_NAME);  
        if(IS_ERR(temp)) {  
            err = PTR_ERR(temp);  
            printk(KERN_ALERT"Failed to create hello device.");  
            goto destroy_class;  
        }          
    
        /*在/sys/class/hello/hello目录下创建属性文件val*/  
        err = device_create_file(temp, &dev_attr_val);  
        if(err < 0) {  
            printk(KERN_ALERT"Failed to create attribute val.");                  
            goto destroy_device;  
        }  
    
        dev_set_drvdata(temp, hello_dev);          
    
        printk(KERN_ALERT"Succedded to initialize hello device.\n");  
        return 0;  
    
    destroy_device:  
        device_destroy(hello_class, dev);  
    
    destroy_class:  
        class_destroy(hello_class);  
    
    destroy_cdev:  
        cdev_del(&(hello_dev->dev));  
    
    cleanup:  
        kfree(hello_dev);  
    
    unregister:  
        unregister_chrdev_region(MKDEV(hello_major, hello_minor), 1);  
    
    fail:  
        return err;  
    }  
    
    /*模块卸载方法*/  
    static void __exit hello_exit(void) {  
        dev_t devno = MKDEV(hello_major, hello_minor);  
    
        printk(KERN_ALERT"hello_exit\n");          
    
        /*销毁设备类别和设备*/  
        if(hello_class) {  
            device_destroy(hello_class, MKDEV(hello_major, hello_minor));  
            class_destroy(hello_class);  
        }          
    
        /*删除字符设备和释放设备内存*/  
        if(hello_dev) {  
            cdev_del(&(hello_dev->dev));  
            kfree(hello_dev);  
        }          
        if(hello_dev->val != NULL){
         kfree(hello_dev->val);
        }
        /*释放设备号*/  
        unregister_chrdev_region(devno, 1);  
    }  
    
    MODULE_LICENSE("GPL");  
    MODULE_DESCRIPTION("Test Driver");  
    
    module_init(hello_init);  
    module_exit(hello_exit);  
    
    

    hello.h

    文件如下:

    #ifndef _HELLO_TEST_H_  
    #define _HELLO_ANDROID_H_  
    
    #include <linux/cdev.h>  
    #include <linux/semaphore.h>  
    
    #define HELLO_DEVICE_NODE_NAME  "hello"  
    #define HELLO_DEVICE_FILE_NAME  "hello"  
    #define HELLO_DEVICE_CLASS_NAME "hello"  
    
    struct hello_test_dev {  
        char * val;  
        struct semaphore sem;  
        struct cdev dev;  
    };  
    
    #endif  

    二。编译驱动

    在linux源码目录的driver下新建hello目录,把hello.c和hello.h文件放入其中。新增Makefile和Kconfig文件:

    1.Makefile,用于编译驱动

    obj-$(CONFIG_HELLO) += hello.o

    2.Kconfig

           config HELLO
               tristate "Test Driver"
               default n
               help
               This is the test driver.
    

    3修改driver目录下的Makefile:

    添加如下一项:

    obj-$(CONFIG_HELLO) += hello/

    4.修改driver目录下的Kconfig

    添加如下一项:

    source "drivers/hello/Kconfig"

    5.make menuconfig

    如果对编译linux kernel不熟悉请自行百度。
    配置界面如下:
    这里写图片描述

    可以看到这里出现了我们在Kconfig中添加的Test Driver选项,我们把它选择成以模块的形式编译,这更有利于我们的测试,这样我们就不需要重新少些linux kernel了。Android的linux kernel一般是打包进boot.img文件的,如果想把模块编译进Linux内核,并且重写烧写linux kernel ,建议把kernel放到out/target/product/xxx/目录下,然后使用make bootimage-nodeps能快速生成boot.img文件,具体kernel放置的位置还需要看android编译系统相关配置,这里就不深究了。

    6.make -j16

    执行make -j16(-j16标示使用16个cpu来编译,只是个请求),这个过程还是很快的,几分钟就可以编译成功。编译后的hello目录如下:
    这里写图片描述
    可以看到生成了hello.ko文件。

    三.使用/sys/class/hello/hello/val 进行测试

    1.把hello.ko拷贝到android设备上

    建议直接使用adb push hello.ko /data 即可,也可以用U盘拷贝。总之,把它放到android设备上。

    2.装载驱动

    cd /data
    insmod hello.ko
    这个时候可以看到/dev/hello /sys/class/hello/hello/val文件已经出现

    3.测试

    输入命令:echo haha > val
    打印如下:
    [ 9641.053505] hello_val_store.buf: haha
    [ 9641.053505] count:5
    [ 9641.060167] __hello_set_val.buf: haha
    [ 9641.060167] count:5
    [ 9641.066841] __hello_set_val.dev->val: hello count:5
    [ 9641.073088] __hello_set_val.dev->val: haha
    [ 9641.073088] count:5
    可以看到数据已经写入,
    使用cat val 读取:
    打印如下:
    [ 9644.953496] hello_val_show.
    [ 9644.957127] haha
    [ 9644.957127]
    可以看到haha打印出来了,书名写入是成功的。

    四.使用/dev/hello测试

    首先在android源码的packages目录下新建一个hellotest目录,该目录下新建hellotest.c和Android.mk两个文件。

    1.hellotest.c

    这个文件用来打开/dev/hello文件并尝试读和写字符串操作,并打印相关信息,源码如下:

    #include <stdio.h>  
    #include <stdlib.h>  
    #include <fcntl.h>  
    #define HELLO_DEVICE "/dev/hello"  
    int main(int argc, char** argv)  
    {  
        int fd = -1;  
        char * str = malloc(10);
        //打开/dev/hello
        fd = open(HELLO_DEVICE, O_RDWR);  
        if(fd == -1) {  
            printf("Failed to open device %s.\n", HELLO_DEVICE);  
            return -1;  
        }  
    
        printf("Read original value:\n"); 
        //先读一次数据看看
        read(fd, str, 10);  
        printf("read data: %s\n", str);  
        strncpy(str,"nihao",sizeof("nihao"));  
        printf("write nihao\n");  
        //写nihao进去
        write(fd, str, sizeof(str));  
    
        printf("Read the value again:\n");  
        //读看看是不是nihao
            read(fd, str, 10);  
            printf("read data: %s\n", str);  
        close(fd);  
        return 0;  
    }  

    2.Android.mk

    android下编译应用程序使用Android.mk还是很方便的:

          LOCAL_PATH := $(call my-dir)
    
          include $(CLEAR_VARS)
    
          LOCAL_MODULE_TAGS := optional
    
          LOCAL_MODULE := hellotest
    
          LOCAL_SRC_FILES := $(call all-subdir-c-files)
    
          include $(BUILD_EXECUTABLE)

    3.编译

    执行mm命令即可
    编译后的文件在out/target/product/xxx/obj/EXECUTABLES/hellotest_intermediates/目录下,该目录编译后如图:
    这里写图片描述
    关于mm命令编译执行文件的过程,可以参考我的这篇博客: Android编译系统<二>-mm编译单个模块

    4.测试

    使用adb push hellotest /data把hellotest 推送到android设备上来,然后chmod +x hellotest添加可执行权限。
    最后./hellotest
    打印如下:

    Read original value:
    read data: hell
    write nihao
    Read the value again:
    read data: nihao

    可见测试成功。

    展开全文
  • Linux Deploy在Android手机上安装Linux

    万次阅读 多人点赞 2017-01-11 09:24:41
    每小时进行5分钟的活动,能降低患上许多致命疾病的风险。——《程序员健康指南》 ...使用Linux Deploy唯一的好处就是可以充分利用废弃的手机,而且手机具有省电,便捷的特点。...安卓手机一台,配置...
  • Linux Deploy在安卓手机安装LINUX系统

    万次阅读 多人点赞 2018-01-31 16:49:56
    Linux deploy https://github.com/meefik/linuxdeploy/releases Linux系统支撑软件 Busy Box https://github.com/meefik/busybox/releases Linux deploy支撑软件 ConnectBox https://github.com/c...
  • 是不能直接访问的,把直接访问的任务写在驱动层,而应用访问必须经由驱动层生成一个设备节点,然后把通过这个设备节点访问,然后最终会调用驱动层的代码去访问。所以可以访问/dev/目录下的字符设备并不是说可以直接...
  • 在前面的三篇博客中,我们已经成功向系统注册了我们自己的服务,并通过服务访问hal层,hal层会真正和linux kernel交互。所以这一节,自然就是写一个app来测试我们前面所有的工作是否正确了。 app的编写还是在集成...
  • Android硬件抽象层(HAL)概要介绍和学习计划...接着,在Ubuntu上为Android系统编写Linux内核驱动程序一文中举例子说明了如何在Linux内核编写驱动程序。在这一篇文章中,我们将继续介绍Android系统硬件驱动程序的另一
  • 利用Linux自带iptables配置IP访问规则,即可做到防火墙效果         初始化防火墙Chain规则     禁止指定app访问数据网络   禁止指定app访问wifi    ...
  • 前面两篇博客记录了实现Linux驱动和使用HAL层访问Linux驱动的代码,我们分别对这两部分做了测试,他们都正常工作。有了前面的基础,我们就可以实现service层了,我们想系统注册我们自己的service,在service中访问HAL...
  • linux samba 用户访问、匿名访问

    千次阅读 2017-09-05 16:42:55
    1. 配置文件,用户访问[global] workgroup = WORKGROUP #工作组 server string = android samba %v #描述 security = user #security = share 匿名登陆 #security = user #security = domain windows域
  • 不管是 iPhone 还是 Android 安卓. 他们都会有很多 SSH 的 app 提供下载. 有了这些. 我们躺在床上都能轻松控制电脑啦~ 对需要远程控制 Linux 的朋友非常有帮助. 能大大提高你的生产率. 并且 ...
  • 不管是出于什么样地考虑,android系统终究是提供了hardware层来封装了对Linux的驱动的访问,同时为上层提供了一个统一的硬件接口和硬件形态。一.Hardware概述在Hardware层中的一个模块中,主要设计一下三个结构: ...
  • 我用的是Debian,需要使用jmtpfs。 安装:sudo apt-get install mtp-tools jmtpfs准备:sudo mkdir /media/mtp sudo chmod 755 /media/mtp挂载:sudo jmtpfs -o allow_other /media/mtp弹出:sudo umount /media/mtp
  • 手机搭建linux并远程访问一、准备1.android手机2.Termux (下载地址:https://termux.com/)3.云主机(linux)4.本机主机(linux)二、安装1.下载并安装Termux在安卓手机上:2.安装ssh,用于登录linux$apt update //...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 83,902
精华内容 33,560
关键字:

linux安卓访问

linux 订阅