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;
}
网友评论