hello world驱动显示

小鱼儿 2022-05-27 12:15 237阅读 0赞

前几篇博客中,我们实现了内核的移植,根文件系统的制作。
到此,操作系统就可以跑起来了。我们可以来尝试第一个简单的hello world

初步了解

内核了解,我们将Linux内核分成三大部分
Linux

用户空间

用户空间之下是内核空间,Linux 内核正是位于这里。C基础库(如glibc、eglibc、uclinux等)也属于应用程序空间,它提供了连接内核的系统调用接口,还提供了在用户空间应用程序和内核之间进行转换的机制1。

系统调用接口

系统调用接口(SCI,System Call Interface),它实现了一些基本的功能,例如 open()、read()、write()、close()等。系统调用接口之下是内核代码,可以更精确地定义为独立于体系结构的内核代码。这些代码是 Linux 所支持的所有处理器体系结构所通用的。在这些代码之下是依赖于体系结构的代码,构成了通常称为 BSP(Board Support Package)的部分。这些代码用作给定体系结构的处理器和特定于平台的代码。

总览 操作系统原理

  • 系统调用接口
  • 进程管理
  • 内存管理
  • 文件系统
  • 网络管理
  • 设备管理(驱动程序)

Linux内核编程简述

linux内核模块化组成,允许内核在运行时动态地向其中插入或从中删除代码。这些代码(包括相关的子线程、数据、函数入口和函数出口)被一并组合在一个单独的二进制镜像中,即所谓的可装载内核模块中,或简称为模块

内核编程与用户空间编程不同点:

  • 并发问题 内核一直处于繁忙状态,不会出现执行简简单单的代码程序。
  • Linux内核自定义函数 c基础库是在应用程序空间,需要自定义函数使用,如printk()函数。
  • 堆栈小 linux内核堆栈小,自己的函数要共享这个堆栈,较大时,需要动态分配
  • __函数 小心调用 这样的函数一般是底层硬件接口,调用要小心。
  • 区别正常操作系统 一般程序,指针出错或者数组越界,系统一般不会死掉,但内核是发生的。
  • 禁止浮点数运算内核没必要进行浮点运算,加重负担。

hello模块编写

创建目录

  1. [klaus@localhost fl2240maker]$ ls
  2. init+ker_fl2440 jffs+ker_fl2440 ker_fl2440 rootfs_fl2440 ubifs+ker_fl2440 x86_tools
  3. [klaus@localhost fl2240maker]$ mkdir driver
  4. [klaus@localhost fl2240maker]$ cd driver/
  5. [klaus@localhost driver]$

新建hello文件

  1. [klaus@localhost fl2240maker]$ cd driver/
  2. [klaus@localhost driver]$ vim kernel_hello.c
  3. [klaus@localhost driver]$ cat kernel_hello.c
  4. #include <linux/init.h>
  5. #include <linux/module.h>
  6. #include <linux/kernel.h>
  7. static __init int hello_init(void){
  8. printk(KERN_ALERT "Hello, LingYun IoT Studio!\n");
  9. return 0;
  10. }
  11. static __exit void hello_exit(void){
  12. printk(KERN_ALERT "Goodbye, I have found a good job!\n");
  13. }
  14. module_init(hello_init);
  15. module_exit(hello_exit);
  16. MODULE_DESCRIPTION("Linux Kernel hello module (C) LingYun IoT Studio");
  17. MODULE_LICENSE("Dual BSD/GPL");
  18. [klaus@localhost x86]$

编译调试

  1. [klaus@localhost driver]$ mkdir x86
  2. [klaus@localhost driver]$ cd x86/
  3. [klaus@localhost x86]$ ln -s ../kernel_hello.c [klaus@localhost x86]$ vim Makefile [klaus@localhost x86]$ cat Makefile KERNAL_DIR ?= /lib/modules/$(shell uname -r)/build
  4. PWD := $(shell pwd)
  5. obj-m := kernel_hello.o modules:
  6. $(MAKE) -C $(KERNAL_DIR) M=$(PWD) modules
  7. @make clear
  8. clear:
  9. @rm -f *.o *.cmd *.mod.c
  10. @rm -rf *~ core .depend .tmp_versions Module.symvers modules.order -f
  11. @rm -f .*ko.cmd .*.o.cmd .*.o.d
  12. @rm -f *.unsigned
  13. clean:
  14. @rm -f hello.ko
  15. [klaus@localhost x86]$ make
  16. make -C /lib/modules/2.6.32-696.el6.x86_64/build M=/home/klaus/fl2240maker/driver/x86 modules make[1]: Entering directory `/usr/src/kernels/2.6.32-696.el6.x86_64'
  17. CC [M] /home/klaus/fl2240maker/driver/x86/kernel_hello.o
  18. Building modules, stage 2.
  19. MODPOST 1 modules
  20. CC /home/klaus/fl2240maker/driver/x86/kernel_hello.mod.o
  21. LD [M] /home/klaus/fl2240maker/driver/x86/kernel_hello.ko.unsigned
  22. NO SIGN [M] /home/klaus/fl2240maker/driver/x86/kernel_hello.ko
  23. make[1]: Leaving directory `/usr/src/kernels/2.6.32-696.el6.x86_64'
  24. make[1]: Entering directory `/home/klaus/fl2240maker/driver/x86'
  25. make[1]: Leaving directory `/home/klaus/fl2240maker/driver/x86'
  26. [klaus@localhost x86]$

ARM开发板上测试

ARM环境编译

  1. [klaus@localhost driver]$ ls
  2. kernel_hello.c x86
  3. [klaus@localhost driver]$ vim Makefile
  4. [klaus@localhost driver]$ cat Makefile
  5. LINUX_SRC = ${ shell pwd}/../linux/linux-3.0/
  6. CROSS_COMPILE=/opt/xtools/arm920t/bin/arm-linuxINST_PATH=/tftp
  7. PWD := $(shell pwd)
  8. EXTRA_CFLAGS+=-DMODULE
  9. obj-m += kernel_hello.o
  10. modules:
  11. @make -C $(LINUX_SRC) M=$(PWD) modules
  12. @make clear
  13. uninstall:
  14. rm -f ${ INST_PATH}/*.ko
  15. install: uninstall
  16. cp -af *.ko ${ INST_PATH}
  17. clear:
  18. @rm -f *.o *.cmd *.mod.c
  19. @rm -rf *~ core .depend .tmp_versions Module.symvers modules.order -f
  20. @rm -f .*ko.cmd .*.o.cmd .*.o.d
  21. clean: clear
  22. @rm -f *.ko
  23. [klaus@localhost driver]$ make
  24. make: *** /home/klaus/fl2240maker/driver/../linux/linux-3.0/: No such file or directory. Stop.
  25. make: *** [modules] Error 2
  26. [klaus@localhost driver]$

文件生成

  1. [klaus@localhost fl2240maker]$ cp -r driver/* hello_initker/driver/ cp: cannot create regular file `hello_initker/driver/kernel_hello.c': Permission denied cp: cannot create regular file `hello_initker/driver/Makefile': Permission denied
  2. cp: cannot create directory `hello_initker/driver/x86': Permission denied
  3. [klaus@localhost fl2240maker]$ sudo cp -r driver/* hello_initker/driver/ [klaus@localhost fl2240maker]$ cd .. [klaus@localhost ~]$ cd fl2240maker/hello_initker/driver/
  4. [klaus@localhost driver]$ make
  5. make[1]: Entering directory `/home/klaus/fl2240maker/hello_initker/linux/linux-3.0'
  6. mkdir: cannot create directory `/home/klaus/fl2240maker/hello_initker/driver/.tmp_versions': Permission denied
  7. CC [M] /home/klaus/fl2240maker/hello_initker/driver/kernel_hello.o
  8. /home/klaus/fl2240maker/hello_initker/driver/kernel_hello.c:15: fatal error: opening dependency file /home/klaus/fl2240maker/hello_initker/driver/.kernel_hello.o.d: Permission denied
  9. compilation terminated.
  10. make[2]: *** [/home/klaus/fl2240maker/hello_initker/driver/kernel_hello.o] Error 1
  11. make[1]: *** [_module_/home/klaus/fl2240maker/hello_initker/driver] Error 2 make[1]: Leaving directory `/home/klaus/fl2240maker/hello_initker/linux/linux-3.0'
  12. make: *** [modules] Error 2
  13. [klaus@localhost driver]$ sudo make
  14. make[1]: Entering directory `/home/klaus/fl2240maker/hello_initker/linux/linux-3.0'
  15. CC [M] /home/klaus/fl2240maker/hello_initker/driver/kernel_hello.o
  16. Building modules, stage 2.
  17. MODPOST 1 modules
  18. CC /home/klaus/fl2240maker/hello_initker/driver/kernel_hello.mod.o
  19. LD [M] /home/klaus/fl2240maker/hello_initker/driver/kernel_hello.ko
  20. make[1]: Leaving directory `/home/klaus/fl2240maker/hello_initker/linux/linux-3.0'
  21. make[1]: Entering directory `/home/klaus/fl2240maker/hello_initker/driver'
  22. make[1]: Leaving directory `/home/klaus/fl2240maker/hello_initker/driver'
  23. [klaus@localhost driver]$

开发板上测试

关闭防火墙,我们用tftp命令将文件下载到开发板上。

  1. ~ >: ifconfig eth0 192.168.10.112
  2. ~ >: ping 192.168.10.8
  3. PING 192.168.10.8 (192.168.10.8): 56 data bytes
  4. 64 bytes from 192.168.10.8: seq=0 ttl=128 time=3.837 ms
  5. 64 bytes from 192.168.10.8: seq=1 ttl=128 time=1.478 ms
  6. ^C
  7. --- 192.168.10.8 ping statistics ---
  8. 2 packets transmitted, 2 packets received, 0% packet loss
  9. round-trip min/avg/max = 1.478/2.657/3.837 ms
  10. ~ >: tftp -gr kernel_hello.ko 192.168.10.8
  11. kernel_hello.ko 100% |*******************************| 21595 0:00:00 ETA
  12. ~ >: ls
  13. apps info media stat
  14. bin init mnt sys
  15. data kernel_hello.ko opt tmp
  16. dev lib proc usr
  17. etc linuxrc root var
  18. home logs sbin
  19. ~ >: lsmod
  20. ~ >: insmod kernel_hello.ko
  21. kernel_hello: module license 'unspecified' taints kernel.
  22. Disabling lock debugging due to kernel taint
  23. Hello, LingYun IoT Studio!
  24. ~ >: insmod kernel_hello.ko
  25. insmod: can't insert 'kernel_hello.ko': File exists ~ >: lsmod kernel_hello 561 0 - Live 0xbf000000 (P) ~ >: rmmod kernel_hello Goodbye, I have found a good job! ~ >: insmod kernel_hello.ko Hello, LingYun IoT Studio! ~ >: lsmod kernel_hello 561 0 - Live 0xbf008000 (P) ~ >: rmmod kernel_hello Goodbye, I have found a good job! ~ >:

  1. 这点非常重要,因为内核和用户空间的应用程序使用的是不同的保护地址空间。每个用户空间的进程都使用自己的虚拟地址空间,而内核则占用单独的地址空间 ↩

发表评论

表情:
评论列表 (有 0 条评论,237人围观)

还没有评论,来说两句吧...

相关阅读

    相关 【转帖】驱动Hello World

    我们学习程序设计,都是从“Hello World”开始的,驱动程序也不例外,今天我就写一个驱动版的“Hello World”来热热身,目的希望大家能对驱动程序的基本框架有所了解

    相关 hello world驱动显示

    前几篇博客中,我们实现了内核的移植,根文件系统的制作。 到此,操作系统就可以跑起来了。我们可以来尝试第一个简单的hello world。 初步了解 内核了解,我们将

    相关 Hello World

    Hello World 一、简述          简单的Hello World程序。(时间久了就会忘,趁着还有印象先记下)     1、C语言:  控制台程序、有窗体

    相关 Hello World

    这是我的第一篇博客,虽然是第一次写博客,但是之前也在微信公众号上写过一些文章(虽然没有阅读量),或多或少对自己产生了一定的帮助。 这些天会考虑将其中一些较为有意义的