Third-party drivers transplant - Black Box transplant

Black box transplantation, transplant i.e. without understanding the details of the driver based on

The main process drive transplantation as follows:

 A black box Transplantation

1, the driver compiled into the kernel

  If the kernel has been already supported drive, it can be directly on the option menu. If not, you need a third-party drivers or to write a driver, transplanted into the kernel.

  1) The third-party drivers into the driver's directory linux-source

  LED driver to copy drivers directory
  LED devices belonging to the character, so on the drivers/char/directory

   2) modify the Makefile so that drivers compiled into the kernel (Makefile in the corresponding directory)

   make uImage to compile the kernel

   3) Test-drive

Writing to image development board

Ubuntu compile the driver test code, and copied to the root file system

 1 #include <stdio.h>
 2 #include <fcntl.h>
 3 #include <unistd.h>
 4 #include <stdlib.h>
 5 #include <sys/ioctl.h>
 6 
 7 #define LED_MAGIC 'L'
 8 #define LED_ON  _IOW(LED_MAGIC, 1, int)
 9 #define LED_OFF _IOW(LED_MAGIC, 2, int)
10 
11 int main(int argc, char **argv)
12 {
13     int fd;
14     
15     fd = open("/dev/led", O_RDWR);
16      IF (FD < 0 ) {
 . 17          perror ( " Open " );
 18 is          Exit ( . 1 );
 . 19      }
 20 is      
21 is      the printf ( " Open LED OK \ n- " );
 22 is      
23 is      // achieve LED blinks 
24      the while ( . 1 )
 25      {
 26 is        the ioctl (FD, LED_ON); // illumination lamp 
27        usleep ( 100000 );
 28        the ioctl (FD, LED_OFF); // unlit 
29       usleep(100000);
30     }
31     
32     return 0;
33 }
fs4412_app.c

Run app.c, test-driven on the board

 Error, see app.c

 That, you need to create a device file

  4) Create a device file

In fs4412_led_drv.c, the acquisition device number

 Based device number 501, as the minor device number 0

Creating device files on the board

mknod  /dev/led c 501 0

It is performed again, and the LED flashes can be found print information corresponding output

 

Second, by adding configure to drive Kconfig

  If the above methods are the same as in the actual development, driven to manually add folders, modify Makefile, you do not want to load the driver and from time to delete the file, then when the number of drive a lot, would very complicated. Can be in a graphical interface, added or subtracted by the drive configuration Kconfig.

  1) led to add a device driver in the Kconfig

  Kconfig to enter the next subdirectory

  

   make menuconfig

  

   Open the help information

  

   You can see related drivers already in the graphical interface

  2) modify Makefile

  The original information notes, add configuration items

  

   3) Select the graphical interface into the kernel does not compile , test

  

  4) Compile the test

  make menuconfig

  In compiling the interface did not see fs4412_led_drv.o compiled in, then take a look at the board

  

   led drive does not compiled into the kernel.

 3, independent drive modules compiled

   In front of the two methods used to load the driver, but both methods are determined by adding the kernel directory file, and modify Makefile Kconfig in the corresponding directory. For this new drive is not good management. Therefore, we can create a single directory, the directory can be anywhere outside the kernel, the drive to load independent. How to achieve?

 1) configured as a module method

  An outer core driver module separately compiled

  创建目录,

  

  1 #include <linux/kernel.h>
  2 #include <linux/module.h>
  3 #include <linux/fs.h>    
  4 #include <linux/cdev.h>
  5 #include <asm/io.h>
  6 
  7 
  8 #define LED_MAGIC 'L'
  9 #define LED_ON  _IOW(LED_MAGIC, 1, int)
 10 #define LED_OFF _IOW(LED_MAGIC, 2, int)
 11 
 12 #define LED_MA   501
 13 #define LED_MI    0
 14 #define LED_NUM   1
 15 
 16 #define LED_CON 0x11000C20
 17 #define LED_DAT 0x11000C24
 18 
 19 
 20 struct cdev cdev;
 21 
 22 unsigned int *ledcon;
 23 unsigned int *leddat;
 24 
 25 int led_open (struct inode *inode, struct file *file)
 26 {
 27     printk("led_open\n");
 28 
 29 
 30     ledcon = ioremap(LED_CON, 4);
 31     if(ledcon == NULL) {
 32         printk("ioremap LED_CON error\n");
 33         return -1;
 34     }
 35     writel(0x01, ledcon);  //设置LED3 GPX1_0 为输出模式
 36 
 37 
 38     leddat = ioremap(LED_DAT, 4);
 39     if(leddat == NULL) {
 40         printk("ioremap LED_DAT error\n");
 41         return -1;
 42     }
 43     writel(1, leddat);    //设置LED3 GPX1_0 输出高电平
 44 
 45     return 0;
 46 }
 47 
 48 int led_release(struct inode *inode, struct file *file)
 49 {
 50     printk("led_close\n");
 51     return 0;
 52 }
 53 
 54 long led_ioctl(struct file *file, unsigned int cmd, unsigned long args)
 55 {
 56     switch(cmd)
 57     {
 58     case  LED_ON:
 59         printk("led on ..\n");
 60         writel(1, leddat);    //设置LED3 GPX1_0 输出高电平
 61         break;
 62     case  LED_OFF:
 63         printk("led off ..\n");      
 64         writel(0, leddat);    //设置LED3 GPX1_0 输出高电平      
 65         break;
 66     default:
 67         printk("no command\n");
 68         break;
 69     }
 70     return 0;
 71 }
 72 
 73 
 74 struct file_operations led_fops = { //文件操作
 75     .owner = THIS_MODULE,
 76     .open = led_open,
 77     .release =led_release,
 78     .unlocked_ioctl = led_ioctl,
 79 };
 80 
 81 static led_init(void)
 82 {
 83     int ret;
 84     dev_t devno = MKDEV(LED_MA, LED_MI); 
 85     ret= register_chrdev_region(devno, LED_NUM, "newled");  //注册设备号
 86     if(ret) {
 87         printk("register_chrdev_region error\n");
 88         return -1;
 89     }
 90 
 91     cdev_init(&cdev, &led_fops);           //初始化字符设备
 92     ret = cdev_add(&cdev, devno, LED_NUM); //添加字符设备到系统中
 93     if (ret < 0) {
 94         printk("cdev_add error\n");
 95         return -1;
 96     }
 97 
 98     printk("Led init  5    \n");
 99     return 0;
100 }
101 
102 static void led_exit(void)
103 {
104     dev_t devno = MKDEV(LED_MA, LED_MI);
105     cdev_del(&cdev);
106     unregister_chrdev_region(devno, LED_NUM);  //取消注册    
107     printk("Led exit\n");    
108 }
109 
110 module_init(led_init);
111 module_exit(led_exit);
112 MODULE_LICENSE("Dual BSD/GPL");
fs4412_led_drv.c
 1 ifeq ($(KERNELRELEASE),)
 2 KERNELDIR ?= /home/linux/kernel/linux-3.14-fs4412
 3 PWD := $(shell pwd)
 4 
 5 all:
 6     $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
 7 
 8 clean:
 9     $(MAKE) -C $(KERNELDIR) M=$(PWD) clean
10     rm -rf a.out
11 
12 else
13     obj-m := fs4412_led_drv.o
14 endif
Makefile

  2)make 编译出ko模块

make之后(Makefile里面将module附加到了make命令后,所以直接make就好了),会自动跳到内核里面,借用内核的Makefile把当前驱动程序编译成ko文件,拷贝到根文件系统

 

  在内核中的Kconfig,配置驱动为模块方式编译进内核

 

将配置项改为tristate后可以选择编译为模块

 

  4)编译所有模块 make modules

  编译模块不需要重新编译内核,make module即可。

 

    会生成以上两个文件,这个ko文件和之前单独在led目录里面make出来的ko是相同的,只是编译的环境不一样而已。选择一个拷贝到nfs即可。

  5)插入模块

  转到ko文件所在目录下

  insmod fs4412_led_drv.ko 

  创建设备节点(应用访问驱动的入口)

  mknod   /dev/led c 501 0

  6)运行测试驱动的应用程序

  ./a.out

 

 

参考博客:

https://blog.csdn.net/m0_37542524/article/details/86476109

 

Guess you like

Origin www.cnblogs.com/y4247464/p/12359830.html