ubuntu helloworld 驱动编译,运行。

使用环境 ubuntu18.04桌面版本

原本觉得这类的文章没什么太大的价值,早就被普及。结果明明记起来以前写这么个demo,现在却不知道从何下手,所以这里重新记录一遍,也是作为重新进入linux驱动开发的开篇。
要编译一个hello.ko,我们需要一个已经编译过的内核源码环境,当前我的ubuntu18.04,看来是默认有源码的。
在 /usr/src/目录下有当前release版本的源码文件 (只有目录结构和头文件)
运行命令#uname -r

root@can-virtual-machine:/work/driver/hello# uname
Linux
root@can-virtual-machine:/work/driver/hello# uname -r
4.15.0-50-generic
root@can-virtual-machine:/work/driver/hello# uname --help
用法:uname [选项]...
输出一组系统信息。如果不跟随选项,则视为只附加-s 选项。

  -a, --all			以如下次序输出所有信息。其中若-p 和
				-i 的探测结果不可知则被省略:
  -s, --kernel-name		输出内核名称
  -n, --nodename		输出网络节点上的主机名
  -r, --kernel-release		输出内核发行号
  -v, --kernel-version     print the kernel version
  -m, --machine            print the machine hardware name
  -p, --processor          print the processor type (non-portable)
  -i, --hardware-platform  print the hardware platform (non-portable)
  -o, --operating-system   print the operating system
      --help		显示此帮助信息并退出
      --version		显示版本信息并退出

GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
请向<http://translationproject.org/team/zh_CN.html> 报告uname 的翻译错误
Full documentation at: <http://www.gnu.org/software/coreutils/uname>
or available locally via: info '(coreutils) uname invocation'

//存在对应的源码
root@can-virtual-machine:/work/driver/hello# ls /usr/src/linux-headers-4.15.0-50-generic/
arch   certs   Documentation  firmware  include  ipc     Kconfig  lib       mm              net      scripts   sound  tools   usr   zfs
block  crypto  drivers        fs        init     Kbuild  kernel   Makefile  Module.symvers  samples  security  spl    ubuntu  virt

参照的《linux设备驱动程序》第二章介绍的hello模块,(这本中文版的,确实如果按照正常阅读习惯很多都读不通顺,所以只能结合上下文“略读”了)。

建一个目录,添加以下两个文件,一个hello.c源文件,和makefile文件。

/*
* hello.c
*/
#include <linux/module.h>
#include <linux/init.h>
MODULE_LICENSE("Dual BSD/GPL");

static int hello_init(void)
{
	printk(KERN_ALERT"Hello, world\n");
	return 0;
}


static void hello_exit(void)
{
	printk(KERN_ALERT"Goodbye, cruel world\n");
}

module_init(hello_init);
module_exit(hello_exit);
#makefile 
obj-m:=hello.o
	KERNELBUILD :=/lib/modules/$(shell uname -r)/build
default:
	make -C $(KERNELBUILD) M=$(shell pwd) modules
clean:
	rm -rf *.o *.ko *.mod.c .*.cmd *.markers *.order *.symvers *tmp_versions

obj-m后面跟的就是最终的模块名,hello, make 会在该目录下自动找到hello.c文件进行编译
hello模块可能依赖多个文件或者模块,那么在obj-m后面就可以添加下面语句hello-objs:=file.o file1.o
modules目标指向obj-m变量中设定的模块

#make
#insmod ./hello.ko
#lsmod | grep "hello"
#rmmod hello

printk打印的内核信息不会再虚拟终端上输出,一般情况下,kernel信息和sys信息被保存在/var/log/ 目录下的kern.log和sys.log,查看可以看到hello模块加载时的hello world 输出:
#cat /var/log/syslog | head -100  //输出了头100行,看到了hello world, 也可以直接grep

发布了96 篇原创文章 · 获赞 27 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/u012459903/article/details/103684032
今日推荐