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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
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
创建目录,
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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");
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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
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