美文网首页
2-安卓底层-java实现调用linux系统调用

2-安卓底层-java实现调用linux系统调用

作者: ibo | 来源:发表于2017-02-16 19:41 被阅读0次

    java实现调用linux系统调用流程:

    java --》 jni ---》 driver

    java 实现的是native方法

    jni 实现的是调用linux 系统调用

    java_open = method结构体 ==> Jopen == jni里调用 => open(系统调用) ==> driver_open

    驱动:ibo.c

    #include <linux/kernel.h>
    #include <linux/module.h>
    #include <linux/cdev.h>
    #include <linux/fs.h>
    #include <linux/device.h>
    #include <asm/uaccess.h>
    #include <asm/io.h>
    
    #define     IBO_MAJOR   505
    #define     IBO_MINOR   0
    #define     IBO_NUM     1
    #define     IBO_NAME    "ibo"
    #define     CLS_NAME    "ibo_cls"
    #define     DEV_NAME    "ibo"
    
    dev_t devno;
    struct cdev ibo_cdev;
    struct class * cls;
    
    static int ibo_open(struct inode *inode,struct file *filp){
        printk("ibo_open success\n");
        return 0;
    }
    
    static int ibo_release(struct inode *inode,struct file *filp){
        printk("ibo_release success\n");
        return 0;
    }
    
    static long ibo_ioctl(struct file *filp,unsigned int cmd,unsigned long arg){
        printk("ibo_ioctl success %d\n",cmd);
        return 0;
    }
    
    struct file_operations ibo_fops={
         .owner          = THIS_MODULE,
         .open           = ibo_open,
         .release        = ibo_release,
         .unlocked_ioctl = ibo_ioctl,
    };
    
    static int ibo_init(void){
        int ret;
        devno = MKDEV(IBO_MAJOR,IBO_MINOR);
        ret = register_chrdev_region(devno,IBO_NUM,IBO_NAME);
        if (ret < 0){
            return -EFAULT;
        }
    
        cdev_init(&ibo_cdev,&ibo_fops);
        ibo_cdev.owner = THIS_MODULE;
    
        cdev_add(&ibo_cdev,devno,IBO_NUM);
    
        cls = class_create(THIS_MODULE,CLS_NAME);
        if (IS_ERR(cls)){
            printk("class_create fail!!!\n");
            return -EFAULT;
        }
    
        device_create(cls,NULL,devno,NULL,DEV_NAME);
    
        printk("ibo_init success\n");
        return 0;
    }
    
    static void ibo_exit(void){
        device_destroy(cls,devno);
        class_destroy(cls);
        cdev_del(&ibo_cdev);
        unregister_chrdev_region(devno,IBO_NUM);
    
        printk("ibo_exit success\n");
        return;
    }
    
    module_init(ibo_init);
    module_exit(ibo_exit);
    
    MODULE_LICENSE("GPL");
    
    

    驱动:Makefile

    ifeq ($(KERNELRELEASE),)
    
    KERNELDIR ?= /lib/modules/$(shell uname -r)/build
    PWD := $(shell pwd)
    
    modules:
        $(MAKE) -C $(KERNELDIR) M=$(PWD) 
    
    clean:
        rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions Module* modules*
    
    .PHONY: modules clean
    
    else
        obj-m := ibo.o
    endif
    
    1.输入make编译生成 .ko 文件
    2.sudo insmod ibo.ko 把模块插入到内核中
    • 输出 ibo_init success 表示成功插入到内核中

    JAVA : Ibo.java

    class Ibo{
        static{
            System.loadLibrary("native");
        }
        private native void open();
        private native void ioctl(int cmd);
        private native void release();
    
    
        public static void main(String[] args) {
    
            Ibo m=new Ibo();
            m.open();
            m.ioctl(525);
            m.release();
        }
    }
    
    3.javac Ibo.java生成 class文件
    4.javah Ibo生成 h文件

    JNI : native.c

    #include <jni.h>
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <stdlib.h>
    #include <sys/ioctl.h>
    
    int fd;
    
    void Jopen(JNIEnv *env,jobject obj){
        fd = open("/dev/ibo",O_RDWR);
        return;
    }
    void Jioctl(JNIEnv *env,jobject obj,jint cmd){
        ioctl(fd,cmd);
        return;
    }
    void Jrelease(JNIEnv *env,jobject obj){
        close(fd);
        return;
    }
    
    JNINativeMethod methods[]={
        "open","()V",(void *)Jopen,
        "ioctl","(I)V",(void *)Jioctl,
        "release","()V",(void *)Jrelease,
    };
    
    JNIEXPORT jint JNICALL
    JNI_OnLoad(JavaVM *vm, void *reserved){
        JNIEnv *env;
        jclass cls;
    
        system("sudo chmod 777 /dev/ibo");
    
        (*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_2);
        if(env == NULL) return JNI_ERR;
    
        cls = (*env)->FindClass(env, "Ibo");
        if(cls == NULL) return JNI_ERR;
    
        (*env)->RegisterNatives(env, cls,methods, sizeof(methods)/sizeof(JNINativeMethod));
    
        return JNI_VERSION_1_2;
    }
    
    5.gcc -shared -fPIC native.c -o libnative.so -I /usr/lib/jvm/java-7-openjdk-amd64/include/ 编译生成 libnative.so 文件
    6.export LD_LIBRARY_PATH=:
    7.java Ibo 运行
    成功调用.PNG

    相关文章

      网友评论

          本文标题:2-安卓底层-java实现调用linux系统调用

          本文链接:https://www.haomeiwen.com/subject/egmhwttx.html