Do-it-yourself from android hardware driver to APP---(1) hardware driver layer

1:

joe@joe-Aspire-Z3730:~$ cd /media/sdb4/aosp/kernel/goldfish/drivers/

2:

joe@joe-Aspire-Z3730:/media/sdb4/aosp/kernel/goldfish/drivers$ mkdir hello

3: Add the hello.h file to the hello directory and refer to the hello.h of the whole process of Android driver development (with pictures and facts)

#ifndef _HELLO_Android_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_PROC_NAME "hello"
#define HELLO_DEVICE_CLASS_NAME "hello"
struct hello_android_dev {
 int val;
 struct semaphore sem;
 struct cdev dev;
};
#endif

4: Add the hello.c file to the hello directory by referring to the link in the post https://blog.csdn.net/eliot_shao/article/details/51864811http://blog.csdn.net/eliot_shao/article/details/51860229

Also refer to https://blog.csdn.net/brantyou/article/details/8651385

/*
 * hello.c -- A simple virtual char device driver
 */
#include <linux/module.h>  
#include <linux/types.h>  
#include <linux/fs.h>  
#include <linux/errno.h>  
#include <linux/mm.h>  
#include <linux/sched.h>  
#include <linux/init.h>  
#include <linux/cdev.h>  
#include <linux/slab.h>
#include <asm/io.h>  
#include <linux/device.h>
#include <asm/uaccess.h>  
MODULE_LICENSE("GPL");
MODULE_AUTHOR("eliot shao");


#define DEVICE_SUM 1

static int hello_open(struct inode *inode, struct file *filp);
static int hello_release(struct inode *, struct file *filp);
static ssize_t hello_read(struct file*, char*, size_t, loff_t*);
static ssize_t hello_write(struct file*, const char*, size_t, loff_t*);

/* the major device number */
static int hello_major = 0;
static int hello_minor = 0;


static struct class* hello_class = NULL;


/* init the file_operations structure */
struct file_operations hello_fops =
{
    .owner = THIS_MODULE,
    .open = hello_open,
    .release = hello_release,
    .read = hello_read,
    .write = hello_write,
};

/* define a cdev device */
struct cdev *cdev;

static int global_var = 0; /* global var */

/* module init */
static int __init hello_init(void)
{
        int ret = 0;
        struct device* temp = NULL;
        dev_t devno = 0;
        printk("hello:hello_init .\n");
        /*动态分配主设备和从设备号*/
        ret = alloc_chrdev_region(&devno, hello_minor, DEVICE_SUM, "hello");
        if(ret < 0) {
            printk(KERN_ALERT"hello:Failed to alloc char dev region.\n");
            goto fail;
        }

        hello_major = MAJOR(devno);
        hello_minor = MINOR(devno);

        cdev = cdev_alloc();
        cdev->owner = THIS_MODULE;
        cdev->ops = &hello_fops;
        if ((ret = cdev_add(cdev, devno, 1)))
        {
            printk(KERN_NOTICE "hello:Error %d adding hello.\n", ret);
            return 0;
        }
        else
            printk("hello:hello register success.\n");
            /*在/sys/class/目录下创建设备类别目录hello*/
        hello_class = class_create(THIS_MODULE, "hello");
        if(IS_ERR(hello_class)) {
            ret = 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, devno, "%s", "hello");
        if(IS_ERR(temp)) {
            ret = PTR_ERR(temp);
            printk(KERN_ALERT"Failed to create hello device.");
            goto destroy_class;
        }      
    return ret;
destroy_class:
    class_destroy(hello_class);
destroy_cdev:
    cdev_del(cdev);
fail:
    return ret;
}

/* module exit */
static void __exit hello_exit(void)
{
    dev_t devno = MKDEV(hello_major, 0);

    /* remove cdev from kernel */
    cdev_del(cdev);

    /* unregister the device driver */
    unregister_chrdev_region(devno, 1);

    /* free the dev structure */
    if(cdev)
        kfree(cdev);
    cdev = NULL;
}

/* open device */
static int hello_open(struct inode *inode, struct file *filp)
{
    int ret = 0;
    printk("KERNEL:open success.\n");
    return ret;
}

/* release device */
static int hello_release(struct inode *inode, struct file *filp)
{
    printk("KERNEL:release success.\n");
    return 0;
}

/* read device */
static ssize_t hello_read(struct file *filp, char *buf, size_t len, loff_t *off)
{
    printk("KERNEL:reading...\n");
    if(copy_to_user(buf, &global_var, sizeof(int)))
    {
        return -EFAULT;
    }
    return sizeof(int);
}

/* write device */
static ssize_t hello_write(struct file *filp, const char *buf, size_t len, loff_t *off)
{
    printk("KERNEL:writing...\n");
    if(copy_from_user(&global_var, buf, sizeof(int)))
    {
        return -EFAULT;
    }
    return sizeof(int);
}

/* module register */
module_init(hello_init);
module_exit(hello_exit);

5: Add a line to the Makefile in the /media/sdb4/aosp/kernel/goldfish/drivers directory:

obj-$(CONFIG_HELLO)		+= hello/

6: Add a line to Kconfig in the /media/sdb4/aosp/kernel/goldfish/drivers directory (pay attention to the location):

menu "Device Drivers"
。。。。。
source "drivers/hello/Kconfig"
。。。
endmenu

7: Add a Makefile to the /media/sdb4/aosp/kernel/goldfish/drivers/hello directory, the contents are:

obj-$(CONFIG_HELLO)	+= hello.o

8: Add a Kconfig file to the /media/sdb4/aosp/kernel/goldfish/drivers/hello directory, the content is

config HELLO
tristate "First Android Driver"
default n
help
This is first Android Deiver for demo

9:

joe@joe-Aspire-Z3730:/media/sdb4/aosp/kernel/goldfish$  export CROSS_COMPILE=arm-eabi-
joe@joe-Aspire-Z3730:/media/sdb4/aosp/kernel/goldfish$ export ARCH=arm
joe@joe-Aspire-Z3730:/media/sdb4/aosp/kernel/goldfish$  export SUBARCH=arm

10:

joe@joe-Aspire-Z3730:/media/sdb4/aosp/kernel/goldfish$ make goldfish_armv7_defconfig

#
# configuration written to .config
#

#### make completed successfully (7 seconds) ####

11:

joe@joe-Aspire-Z3730:/media/sdb4/aosp/kernel/goldfish$ make
scripts/kconfig/conf --silentoldconfig Kconfig
  CHK     include/linux/version.h
  CHK     include/generated/utsrelease.h
make[1]: `include/generated/mach-types.h' is up to date.
  CALL    scripts/checksyscalls.sh
  CHK     include/generated/compile.h
  GZIP    kernel/config_data.gz
  CHK     kernel/config_data.h
  UPD     kernel/config_data.h
  CC      kernel/configs.o
  LD      kernel/built-in.o
  LD      vmlinux.o
  MODPOST vmlinux.o
  GEN     .version
  CHK     include/generated/compile.h
  UPD     include/generated/compile.h
  CC      init/version.o
  LD      init/built-in.o
  LD      .tmp_vmlinux1
  KSYM    .tmp_kallsyms1.S
  AS      .tmp_kallsyms1.o
  LD      .tmp_vmlinux2
  KSYM    .tmp_kallsyms2.S
  AS      .tmp_kallsyms2.o
  LD      vmlinux
  SYSMAP  System.map
  SYSMAP  .tmp_System.map
  OBJCOPY arch/arm/boot/Image
  Kernel: arch/arm/boot/Image is ready
  GZIP    arch/arm/boot/compressed/piggy.gzip
  AS      arch/arm/boot/compressed/piggy.gzip.o
  LD      arch/arm/boot/compressed/vmlinux
  OBJCOPY arch/arm/boot/zImage
  Kernel: arch/arm/boot/zImage is ready

#### make completed successfully (29 seconds) ####
总感觉不可能有这么快的编译速度?????

12: Re-enter the aosp directory

joe@joe-Aspire-Z3730:/media/sdb4/aosp$ emulator -kernel ./kernel/goldfish/arch/arm/boot/zImage

13: I don't see the hello.o file in the /media/sdb4/aosp/kernel/goldfish/drivers/hello directory although the emulator is started with the new kernel

14: No hello device seen in /dev nor /proc

joe@joe-Aspire-Z3730:/media/sdb4/aosp$ adb shell
root@generic:/ # cd dev
root@generic:/dev # ls
__properties__
ashmem
binder
block
console
cpu_dma_latency
cpuctl
device-mapper
eac
fscklogs
full
fuse
graphics
input
kmem
kmsg
loop-control
mem
memcg
mtd
network_latency
network_throughput
null
psaux
ptmx
pts
qemu_pipe
random
rtc0
socket
tty
tty0
tty1
tty10
tty11
tty12
tty13
tty14
tty15
tty16
tty17
tty18
tty19
tty2
tty20
tty21
tty22
tty23
tty24
tty25
tty26
tty27
tty28
tty29
tty3
tty30
tty31
tty32
tty33
tty34
tty35
tty36
tty37
tty38
tty39
tty4
tty40
tty41
tty42
tty43
tty44
tty45
tty46
tty47
tty48
tty49
tty5
tty50
tty51
tty52
tty53
tty54
tty55
tty56
tty57
tty58
tty59
tty6
tty60
tty61
tty62
tty63
tty7
tty8
tty9
ttyS0
ttyS1
ttyS2
tun
urandom
vcs
vcs1
vcsa
vcsa1
xt_qtaguid
zero
root@generic:/dev # cd /proc
root@generic:/proc # ls
1
10
1013
1030
1061
1081
1098
11
1125
1162
1178
1186
12
13
139
14
2
25
26
27
28
29
3
30
31
33
337
34
37
39
40
43
447
45
46
47
48
49
5
50
51
52
54
57
58
587
59
6
60
61
62
63
64
646
65
66
663
682
7
709
73
739
783
8
822
839
897
9
923
940
963
995
buddyinfo
bus
cgroups
cmdline
config.gz
consoles
cpu
cpuinfo
crypto
devices
diskstats
dma-mappings
driver
execdomains
fb
filesystems
fs
interrupts
iomem
ioports
irq
kallsyms
kmsg
kpagecount
kpageflags
loadavg
locks
meminfo
misc
mounts
mtd
net
pagetypeinfo
partitions
sched_debug
schedstat
self
slabinfo
softirqs
stat
swaps
sys
sysrq-trigger
sysvipc
timer_list
tty
uptime
version
vmallocinfo
vmstat
yaffs
zoneinfo

15: Modify the Kconfig file in the /media/sdb4/aosp/kernel/goldfish/drivers/hello directory

config HELLO
tristate "First Android Driver"
default m
help
This is first Android Deiver for demo

16: Re-execute steps 10 and 11, and then find that the hello.o file appears in the hello directory, indicating that the driver is compiled

17:

joe@joe-Aspire-Z3730:/media/sdb4/aosp/kernel/goldfish$ cd ../..
joe@joe-Aspire-Z3730:/media/sdb4/aosp$  emulator -kernel ./kernel/goldfish/arch/arm/boot/zImage &

18: Refer to the android-----emulator to load the kernel compiled by yourself (for driving exercises) https://blog.csdn.net/yf210yf/article/details/9901375 was unsuccessful. Mainly because of permission issues, so modify the Kconfig in the hello directory and compile the driver directly into the kernel

config HELLO
tristate "First Android Driver"
default y
help
This is first Android Deiver for demo

19: Re-do steps 10 and 11

20:

joe@joe-Aspire-Z3730:/media/sdb4/aosp$  emulator -kernel ./kernel/goldfish/arch/arm/boot/zImage &

21: Refer to https://blog.csdn.net/brantyou/article/details/8651385

joe@joe-Aspire-Z3730:/media/sdb4/aosp$ adb shell
root@generic:/ # cd dev
root@generic:/dev # ls
其中就出现了hello,但/proc目录中却没有hello

22: The following post explains how to write the application layer program in the android source code to test the hello driver

https://blog.csdn.net/lzpdz/article/details/50562366

23: As mentioned in 22, first enter the external directory of the source code, and then:

joe@joe-Aspire-Z3730:/media/sdb4/aosp/external$ mkdir hello
joe@joe-Aspire-Z3730:/media/sdb4/aosp/external$ cd hello
joe@joe-Aspire-Z3730:/media/sdb4/aosp/external/hello$ gedit hello.c

    #include <stdio.h>  
    #include <stdlib.h>  
    #include <fcntl.h>  
    #define DEVICE_NAME "/dev/hello"  
    int main(int argc, char** argv)  
    {  
        int fd = -1;  
        int val = 0;  
        fd = open(DEVICE_NAME, O_RDWR);  
        if(fd == -1) {  
            printf("Failed to open device %s.\n", DEVICE_NAME);  
            return -1;  
        }  
          
        printf("Read original value:\n");  
        read(fd, &val, sizeof(val));  
        printf("%d.\n\n", val);  
        val = 5;  
        printf("Write value %d to %s.\n\n", val, DEVICE_NAME);  
            write(fd, &val, sizeof(val));  
          
        printf("Read the value again:\n");  
            read(fd, &val, sizeof(val));  
            printf("%d.\n\n", val);  
        close(fd);  
        return 0;  
    }  

24: Add Android.mk to the hello directory

joe@joe-Aspire-Z3730:/media/sdb4/aosp/external/hello$ gedit Android.mk

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

25: Compile the module in the hello directory

joe@joe-Aspire-Z3730:/media/sdb4/aosp/external/hello$ mm
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=5.1.1
TARGET_PRODUCT=aosp_arm
TARGET_BUILD_VARIANT=eng
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm
TARGET_ARCH_VARIANT=armv7-a
TARGET_CPU_VARIANT=generic
TARGET_2ND_ARCH=
TARGET_2ND_ARCH_VARIANT=
TARGET_2ND_CPU_VARIANT=
HOST_ARCH=x86_64
HOST_OS=linux
HOST_OS_EXTRA=Linux-3.11.0-15-generic-x86_64-with-Ubuntu-12.04-precise
HOST_BUILD_TYPE=release
BUILD_ID=LMY47Z
OUT_DIR=out
============================================
make: Entering directory `/media/46bb100d-2505-4025-8425-34ecf3129209/aosp'
Import includes file: out/target/product/generic/obj/EXECUTABLES/hello_intermediates/import_includes
target thumb C: hello <= external/hello/hello.c
external/hello/hello.c: In function 'main':
external/hello/hello.c:5:14: warning: unused parameter 'argc' [-Wunused-parameter]
 int main(int argc, char** argv)  
              ^
external/hello/hello.c:5:27: warning: unused parameter 'argv' [-Wunused-parameter]
 int main(int argc, char** argv)  
                           ^
target Executable: hello (out/target/product/generic/obj/EXECUTABLES/hello_intermediates/LINKED/hello)
target Symbolic: hello (out/target/product/generic/symbols/system/bin/hello)
Export includes file: external/hello/Android.mk -- out/target/product/generic/obj/EXECUTABLES/hello_intermediates/export_includes
target Strip: hello (out/target/product/generic/obj/EXECUTABLES/hello_intermediates/hello)
Install: out/target/product/generic/system/bin/hello
make: Leaving directory `/media/46bb100d-2505-4025-8425-34ecf3129209/aosp'

#### make completed successfully (4 seconds) ####

26: Repackage the Android system file system.img:

joe@joe-Aspire-Z3730:/media/sdb4/aosp$ make snod
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=5.1.1
TARGET_PRODUCT=aosp_arm
TARGET_BUILD_VARIANT=eng
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm
TARGET_ARCH_VARIANT=armv7-a
TARGET_CPU_VARIANT=generic
TARGET_2ND_ARCH=
TARGET_2ND_ARCH_VARIANT=
TARGET_2ND_CPU_VARIANT=
HOST_ARCH=x86_64
HOST_OS=linux
HOST_OS_EXTRA=Linux-3.11.0-15-generic-x86_64-with-Ubuntu-12.04-precise
HOST_BUILD_TYPE=release
BUILD_ID=LMY47Z
OUT_DIR=out
============================================
build/core/Makefile:1013: Warning: with dexpreopt enabled, you may need a full rebuild.
make snod: ignoring dependencies
Target system fs image: out/target/product/generic/system.img
Running:  mkuserimg.sh out/target/product/generic/system out/target/product/generic/system.img ext4 system 576716800 out/target/product/generic/root/file_contexts
make_ext4fs -T -1 -S out/target/product/generic/root/file_contexts -l 576716800 -a system out/target/product/generic/system.img out/target/product/generic/system
Creating filesystem with parameters:
    Size: 576716800
    Block size: 4096
    Blocks per group: 32768
    Inodes per group: 7040
    Inode size: 256
    Journal blocks: 2200
    Label: 
    Blocks: 140800
    Block groups: 5
    Reserved block group size: 39
Created filesystem with 1468/35200 inodes and 109538/140800 blocks
out/target/product/generic/system.img maxsize=588791808 blocksize=2112 total=576716800 reserve=5947392

#### make completed successfully (19 seconds) ####

27: Restart the emulator

joe@joe-Aspire-Z3730:/media/sdb4/aosp$ emulator -kernel ./kernel/goldfish/arch/arm/boot/zImage  -system out/target/product/generic/system.img

28: Test application hello via adb shell

root@generic:/system/bin # ls
-rwxr-xr-x root     shell        5356 2018-04-25 16:29 hello

29: Through the following test, it shows that the hello driver and hello application we wrote are running successfully.

root@generic:/system/bin # hello                                               
Read original value:
0.

Write value 5 to /dev/hello.

Read the value again:
5.

root@generic:/system/bin # hello     //注意这次执行命令与第一次执行的结果                                          
Read original value:
5.

Write value 5 to /dev/hello.

Read the value again:
5.

默认只有root 用户可读写,而hello_device_open 一般是由上层APP 来调用的,这些APP 一般不具有root 权限,这时候就
导致打开设备文件失败:
Hello Stub: failed to open /dev/hello -- Permission denied.
解决办法是类似于Linux 的udev 规则,打开Android 源代码工程目录下,进入到system/core/rootdir 目录,里面有一个名为
uevent.rc 文件,往里面添加一行:
/dev/hello 0666 root root

备注说明:参考 Android驱动开发全过程(有图有真相)中对此权限操作方面的说明

The mobile phone is not rooted to view data/data/ a certain app file information The author's Xiaomi Mi 3 is not rooted, but I want to easily view some files in the data/data/ directory, directly entering the data will prompt that there is no permission, the way to view is to enter the data After /data/, run the following command, you can directly enter the package of your application, you can use cp or mv to copy or move to the sdcard directory for other operations

run-as package_name

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325207189&siteId=291194637