赞
踩
petalinux-create -t modules --name ps-led --enable
- lkmao@ubuntu:~/peta_prj/linuxPsBase/petalinux_bsp$ petalinux-create -t modules --name ps-led --enable
- INFO: Create modules: ps-led
- INFO: New modules successfully created in /home/lkmao/peta_prj/linuxPsBase/petalinux_bsp/project-spec/meta-user/recipes-modules/ps-led
- INFO: Enabling created component...
- INFO: sourcing build environment
- INFO: silentconfig rootfs
- INFO: ps-led has been enabled
- lkmao@ubuntu:~/peta_prj/linuxPsBase/petalinux_bsp$
cd project-spec/meta-user/recipes-modules/
- lkmao@ubuntu:~/peta_prj/linuxPsBase/petalinux_bsp$ cd project-spec/meta-user/recipes-modules/
- lkmao@ubuntu:~/peta_prj/linuxPsBase/petalinux_bsp/project-spec/meta-user/recipes-modules$ tree
- .
- └── ps-led
- ├── files
- │ ├── COPYING
- │ ├── Makefile
- │ └── ps-led.c
- ├── ps-led.bb
- └── README
-
- 2 directories, 5 files
- lkmao@ubuntu:~/peta_prj/linuxPsBase/petalinux_bsp/project-spec/meta-user/recipes-modules$
当前ps-led.c的代码如下:
- /* ps-led.c - The simplest kernel module.
- * Copyright (C) 2013 - 2016 Xilinx, Inc
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- #include <linux/kernel.h>
- #include <linux/init.h>
- #include <linux/module.h>
- #include <linux/slab.h>
- #include <linux/io.h>
- #include <linux/interrupt.h>
-
- #include <linux/of_address.h>
- #include <linux/of_device.h>
- #include <linux/of_platform.h>
-
- /* Standard module information, edit as appropriate */
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR
- ("Xilinx Inc.");
- MODULE_DESCRIPTION
- ("ps-led - loadable module template generated by petalinux-create -t modules");
-
- #define DRIVER_NAME "ps-led"
-
- /* Simple example of how to receive command line parameters to your module.
- Delete if you don't need them */
- unsigned myint = 0xdeadbeef;
- char *mystr = "default";
-
- module_param(myint, int, S_IRUGO);
- module_param(mystr, charp, S_IRUGO);
-
- struct ps_led_local {
- int irq;
- unsigned long mem_start;
- unsigned long mem_end;
- void __iomem *base_addr;
- };
-
- static irqreturn_t ps_led_irq(int irq, void *lp)
- {
- printk("ps-led interrupt\n");
- return IRQ_HANDLED;
- }
-
- static int ps_led_probe(struct platform_device *pdev)
- {
- struct resource *r_irq; /* Interrupt resources */
- struct resource *r_mem; /* IO mem resources */
- struct device *dev = &pdev->dev;
- struct ps_led_local *lp = NULL;
-
- int rc = 0;
- dev_info(dev, "Device Tree Probing\n");
- /* Get iospace for the device */
- r_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!r_mem) {
- dev_err(dev, "invalid address\n");
- return -ENODEV;
- }
- lp = (struct ps_led_local *) kmalloc(sizeof(struct ps_led_local), GFP_KERNEL);
- if (!lp) {
- dev_err(dev, "Cound not allocate ps-led device\n");
- return -ENOMEM;
- }
- dev_set_drvdata(dev, lp);
- lp->mem_start = r_mem->start;
- lp->mem_end = r_mem->end;
-
- if (!request_mem_region(lp->mem_start,
- lp->mem_end - lp->mem_start + 1,
- DRIVER_NAME)) {
- dev_err(dev, "Couldn't lock memory region at %p\n",
- (void *)lp->mem_start);
- rc = -EBUSY;
- goto error1;
- }
-
- lp->base_addr = ioremap(lp->mem_start, lp->mem_end - lp->mem_start + 1);
- if (!lp->base_addr) {
- dev_err(dev, "ps-led: Could not allocate iomem\n");
- rc = -EIO;
- goto error2;
- }
-
- /* Get IRQ for the device */
- r_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!r_irq) {
- dev_info(dev, "no IRQ found\n");
- dev_info(dev, "ps-led at 0x%08x mapped to 0x%08x\n",
- (unsigned int __force)lp->mem_start,
- (unsigned int __force)lp->base_addr);
- return 0;
- }
- lp->irq = r_irq->start;
- rc = request_irq(lp->irq, &ps_led_irq, 0, DRIVER_NAME, lp);
- if (rc) {
- dev_err(dev, "testmodule: Could not allocate interrupt %d.\n",
- lp->irq);
- goto error3;
- }
-
- dev_info(dev,"ps-led at 0x%08x mapped to 0x%08x, irq=%d\n",
- (unsigned int __force)lp->mem_start,
- (unsigned int __force)lp->base_addr,
- lp->irq);
- return 0;
- error3:
- free_irq(lp->irq, lp);
- error2:
- release_mem_region(lp->mem_start, lp->mem_end - lp->mem_start + 1);
- error1:
- kfree(lp);
- dev_set_drvdata(dev, NULL);
- return rc;
- }
-
- static int ps_led_remove(struct platform_device *pdev)
- {
- struct device *dev = &pdev->dev;
- struct ps_led_local *lp = dev_get_drvdata(dev);
- free_irq(lp->irq, lp);
- iounmap(lp->base_addr);
- release_mem_region(lp->mem_start, lp->mem_end - lp->mem_start + 1);
- kfree(lp);
- dev_set_drvdata(dev, NULL);
- return 0;
- }
-
- #ifdef CONFIG_OF
- static struct of_device_id ps_led_of_match[] = {
- { .compatible = "vendor,ps-led", },
- { /* end of list */ },
- };
- MODULE_DEVICE_TABLE(of, ps_led_of_match);
- #else
- # define ps_led_of_match
- #endif
-
-
- static struct platform_driver ps_led_driver = {
- .driver = {
- .name = DRIVER_NAME,
- .owner = THIS_MODULE,
- .of_match_table = ps_led_of_match,
- },
- .probe = ps_led_probe,
- .remove = ps_led_remove,
- };
-
- static int __init ps_led_init(void)
- {
- printk("<1>Hello module world.\n");
- printk("<1>Module parameters were (0x%08x) and \"%s\"\n", myint,
- mystr);
-
- return platform_driver_register(&ps_led_driver);
- }
-
-
- static void __exit ps_led_exit(void)
- {
- platform_driver_unregister(&ps_led_driver);
- printk(KERN_ALERT "Goodbye module world.\n");
- }
-
- module_init(ps_led_init);
- module_exit(ps_led_exit);
Makefile的代码:
- obj-m := ps-led.o
-
- MY_CFLAGS += -g -DDEBUG
- ccflags-y += ${MY_CFLAGS}
-
- SRC := $(shell pwd)
-
- all:
- $(MAKE) -C $(KERNEL_SRC) M=$(SRC)
-
- modules_install:
- $(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install
-
- clean:
- rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c
- rm -f Module.markers Module.symvers modules.order
- rm -rf .tmp_versions Modules.symvers
修改ps-led.c文件的代码如下:这是一个最简单的驱动代码,且是平台无关的。
- #include <linux/module.h>
- #include <linux/init.h>
-
- #define DEBUG_INFO(format,...) printk(KERN_ERR"%s:%d"format"\n",\
- __func__,__LINE__,##__VA_ARGS__)
-
- static int __init ps_led_init(void)
- {
- DEBUG_INFO("init");
- printk(KERN_NOTICE"KERN_NOTICE\n");
- printk(KERN_WARNING"KERN_WARNING\n");
- return 0;
- }
-
- static int __exit ps_led_exit(void)
- {
- DEBUG_INFO("init");
-
- }
-
-
- module_init(ps_led_init);
- module_exit(ps_led_exit);
-
- MODULE_LICENSE("GPL");
在工程目录执行petalinux-build:
- lkmao@ubuntu:~/peta_prj/linuxPsBase/petalinux_bsp$ petalinux-build
- INFO: sourcing build tools
- [INFO] building project
- [INFO] sourcing build environment
- [INFO] generating user layers
- [INFO] generating workspace directory
- INFO: bitbake petalinux-image-minimal
- Loading cache: 100% |#############################################################################################| Time: 0:00:00
- Loaded 4228 entries from dependency cache.
- Parsing recipes: 100% |###########################################################################################| Time: 0:00:04
- Parsing of 2962 .bb files complete (2959 cached, 3 parsed). 4231 targets, 168 skipped, 0 masked, 0 errors.
- NOTE: Resolving any missing task queue dependencies
- Initialising tasks: 100% |########################################################################################| Time: 0:00:04
- Checking sstate mirror object availability: 100% |################################################################| Time: 0:00:00
- Sstate summary: Wanted 149 Found 9 Missed 140 Current 864 (6% match, 86% complete)
- NOTE: Executing Tasks
- NOTE: Setscene tasks completed
- WARNING: device-tree-xilinx-v2020.1+gitAUTOINC+bc84458333-r0 do_package: device-tree: NOT adding alternative provide /boot/device-tree.dtb: /boot/device-tree-999.dtb does not exist
- NOTE: u-boot-xlnx: compiling from external source tree /home/lkmao/Downloads/petalinux_offline_pkg/u-boot-xlnx-xilinx-v2020.1
- NOTE: Tasks Summary: Attempted 3640 tasks of which 3427 didn't need to be rerun and all succeeded.
- Summary: There was 1 WARNING message shown.
- INFO: Failed to copy built images to tftp dir: /tftpboot
- [INFO] successfully built project
- lkmao@ubuntu:~/peta_prj/linuxPsBase/petalinux_bsp$
编译完成后搜索ps-led.ko文件
- lkmao@ubuntu:~/peta_prj/linuxPsBase/petalinux_bsp$ find . -name "ps-led.ko"
- ./build/tmp/sysroots-components/zynqmp_generic/ps-led/lib/modules/5.4.0/extra/ps-led.ko
- lkmao@ubuntu:~/peta_prj/linuxPsBase/petalinux_bsp$
- modname:=ps-led
- obj-m:=$(modname).o
- PWD :=$(shell pwd)
- MAKE :=make
- KERNELDIR = /home/lkmao/peta_prj/linuxPsBase/petalinux_bsp/build/tmp/work-shared/zynqmp-generic/kernel-build-artifacts
- CROSS_COMPILE=aarch64-linux-gnu-
- ARCH=arm64
- all:
- $(MAKE) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C $(KERNELDIR) M=$(PWD) modules
- clean:
- rm -rf $(modname).ko *.o *mod* \.*cmd *odule* .tmp_versions
- .PHONY: all clean
然后使用make编译:
- lkmao@ubuntu:~/peta_prj/linuxPsBase/drivers/ps-led$ make
- make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -C /home/lkmao/peta_prj/linuxPsBase/petalinux_bsp/build/tmp/work-shared/zynqmp-generic/kernel-build-artifacts M=/home/lkmao/peta_prj/linuxPsBase/drivers/ps-led modules
- make[1]: Entering directory '/home/lkmao/peta_prj/linuxPsBase/petalinux_bsp/build/tmp/work-shared/zynqmp-generic/kernel-build-artifacts'
- CC [M] /home/lkmao/peta_prj/linuxPsBase/drivers/ps-led/ps-led.o
- Building modules, stage 2.
- MODPOST 1 modules
- CC [M] /home/lkmao/peta_prj/linuxPsBase/drivers/ps-led/ps-led.mod.o
- LD [M] /home/lkmao/peta_prj/linuxPsBase/drivers/ps-led/ps-led.ko
- make[1]: Leaving directory '/home/lkmao/peta_prj/linuxPsBase/petalinux_bsp/build/tmp/work-shared/zynqmp-generic/kernel-build-artifacts'
- lkmao@ubuntu:~/peta_prj/linuxPsBase/drivers/ps-led$ ls
- Makefile modules.order Module.symvers ps-led.c ps-led.ko ps-led.mod ps-led.mod.c ps-led.mod.o ps-led.o
- lkmao@ubuntu:~/peta_prj/linuxPsBase/drivers/ps-led$
编译后,看到生成了ps-led.ko文件。
如何确定内核的路径:petalinux工程中创建一个驱动模块:
petalinux-create -t modules --name ps-led --enable
然后生成的ps-led.c中添加一些错误。使用petalinux-build编译工程,查看报错信息,如下所示,
创建本地挂载目录,配置IP地址,测试网络,挂载NFS服务。
- root@petalinux:~# mkdir server
- root@petalinux:~# ifconfig eth0 192.168.0.3
- root@petalinux:~# ping 192.168.0.111
- PING 192.168.0.111 (192.168.0.111): 56 data bytes
- 64 bytes from 192.168.0.111: seq=0 ttl=64 time=1.028 ms
- 64 bytes from 192.168.0.111: seq=1 ttl=64 time=0.399 ms
- ^C
- --- 192.168.0.111 ping statistics ---
- 2 packets transmitted, 2 packets received, 0% packet loss
- round-trip min/avg/max = 0.399/0.713/1.028 ms
- root@petalinux:~#
- root@petalinux:~# mount -t nfs -o nolock 192.168.0.111:/home/lkmao/work/nfsroot ./server
- root@petalinux:~#
在虚拟机中,将ko文件复制到nfs目录
- lkmao@ubuntu:~/peta_prj/linuxPsBase/drivers/ps-led$ cp ps-led.ko ~/work/nfsroot/
- lkmao@ubuntu:~/peta_prj/linuxPsBase/drivers/ps-led$
复制完毕后,开发板中就可以看到ko文件了:
- root@petalinux:~/server# ls
- hello.txt ps-led.ko
- root@petalinux:~/server#
insmod加载模块:
- root@petalinux:~/server# insmod ps-led.ko
- [ 8549.734998] ps_led: loading out-of-tree module taints kernel.
- [ 8549.741658] ps_led_init:9init
- [ 8549.744631] KERN_NOTICE
- [ 8549.747074] KERN_WARNING
- root@petalinux:~/server#
lsmod查看模块:
- root@petalinux:~/server# lsmod
- Tainted: G
- ps_led 16384 0 - Live 0xffffffc008b75000 (O)
- uio_pdrv_genirq 16384 0 - Live 0xffffffc008b70000
- root@petalinux:~/server#
卸载模块:
- root@petalinux:~/server# rmmod ps-led.ko
- [ 8674.676105] ps_led_exit:17init
- root@petalinux:~/server#
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。