hello world驱动显示

前几篇博客中,我们实现了内核的移植,根文件系统的制作。
到此,操作系统就可以跑起来了。我们可以来尝试第一个简单的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模块编写

创建目录

[klaus@localhost fl2240maker]$ ls
init+ker_fl2440  jffs+ker_fl2440  ker_fl2440  rootfs_fl2440  ubifs+ker_fl2440  x86_tools
[klaus@localhost fl2240maker]$ mkdir driver
[klaus@localhost fl2240maker]$ cd driver/
[klaus@localhost driver]$

新建hello文件

[klaus@localhost fl2240maker]$ cd driver/
[klaus@localhost driver]$ vim kernel_hello.c
[klaus@localhost driver]$ cat kernel_hello.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>

static __init int hello_init(void){
        printk(KERN_ALERT "Hello, LingYun IoT Studio!\n");
        return 0;
}

static __exit void hello_exit(void){
        printk(KERN_ALERT "Goodbye, I have found a good job!\n");
}

module_init(hello_init);
module_exit(hello_exit);
MODULE_DESCRIPTION("Linux Kernel hello module (C) LingYun IoT Studio");
MODULE_LICENSE("Dual BSD/GPL");
[klaus@localhost x86]$

编译调试

[klaus@localhost driver]$ mkdir x86
[klaus@localhost driver]$ cd x86/
[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
PWD := $(shell pwd)
obj-m := kernel_hello.o

modules:
        $(MAKE) -C $(KERNAL_DIR) M=$(PWD) modules
        @make clear

clear:
        @rm -f *.o *.cmd *.mod.c
        @rm -rf *~ core .depend .tmp_versions Module.symvers modules.order -f
        @rm -f .*ko.cmd .*.o.cmd .*.o.d
        @rm -f *.unsigned
clean:
        @rm -f hello.ko
[klaus@localhost x86]$ make
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'
  CC [M]  /home/klaus/fl2240maker/driver/x86/kernel_hello.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/klaus/fl2240maker/driver/x86/kernel_hello.mod.o
  LD [M]  /home/klaus/fl2240maker/driver/x86/kernel_hello.ko.unsigned
  NO SIGN [M] /home/klaus/fl2240maker/driver/x86/kernel_hello.ko
make[1]: Leaving directory `/usr/src/kernels/2.6.32-696.el6.x86_64'
make[1]: Entering directory `/home/klaus/fl2240maker/driver/x86'
make[1]: Leaving directory `/home/klaus/fl2240maker/driver/x86'
[klaus@localhost x86]$

ARM开发板上测试

ARM环境编译

[klaus@localhost driver]$ ls
kernel_hello.c  x86
[klaus@localhost driver]$ vim Makefile
[klaus@localhost driver]$ cat Makefile
LINUX_SRC = ${shell pwd}/../linux/linux-3.0/
CROSS_COMPILE=/opt/xtools/arm920t/bin/arm-linuxINST_PATH=/tftp
PWD := $(shell pwd)
EXTRA_CFLAGS+=-DMODULE
obj-m += kernel_hello.o

modules:
        @make -C $(LINUX_SRC) M=$(PWD) modules
        @make clear

uninstall:
        rm -f ${INST_PATH}/*.ko

install: uninstall
        cp -af *.ko ${INST_PATH}

clear:
        @rm -f *.o *.cmd *.mod.c
        @rm -rf *~ core .depend .tmp_versions Module.symvers modules.order -f
        @rm -f .*ko.cmd .*.o.cmd .*.o.d

clean: clear
        @rm -f *.ko
[klaus@localhost driver]$ make
make: *** /home/klaus/fl2240maker/driver/../linux/linux-3.0/: No such file or directory.  Stop.
make: *** [modules] Error 2
[klaus@localhost driver]$

文件生成

[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
cp: cannot create directory `hello_initker/driver/x86': Permission denied
[klaus@localhost fl2240maker]$ sudo cp -r driver/* hello_initker/driver/
[klaus@localhost fl2240maker]$ cd ..
[klaus@localhost ~]$ cd fl2240maker/hello_initker/driver/
[klaus@localhost driver]$ make
make[1]: Entering directory `/home/klaus/fl2240maker/hello_initker/linux/linux-3.0'
mkdir: cannot create directory `/home/klaus/fl2240maker/hello_initker/driver/.tmp_versions': Permission denied
  CC [M]  /home/klaus/fl2240maker/hello_initker/driver/kernel_hello.o
/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
compilation terminated.
make[2]: *** [/home/klaus/fl2240maker/hello_initker/driver/kernel_hello.o] Error 1
make[1]: *** [_module_/home/klaus/fl2240maker/hello_initker/driver] Error 2
make[1]: Leaving directory `/home/klaus/fl2240maker/hello_initker/linux/linux-3.0'
make: *** [modules] Error 2
[klaus@localhost driver]$ sudo make
make[1]: Entering directory `/home/klaus/fl2240maker/hello_initker/linux/linux-3.0'
  CC [M]  /home/klaus/fl2240maker/hello_initker/driver/kernel_hello.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/klaus/fl2240maker/hello_initker/driver/kernel_hello.mod.o
  LD [M]  /home/klaus/fl2240maker/hello_initker/driver/kernel_hello.ko
make[1]: Leaving directory `/home/klaus/fl2240maker/hello_initker/linux/linux-3.0'
make[1]: Entering directory `/home/klaus/fl2240maker/hello_initker/driver'
make[1]: Leaving directory `/home/klaus/fl2240maker/hello_initker/driver'
[klaus@localhost driver]$

开发板上测试


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

猜你喜欢

转载自blog.csdn.net/klaus_x/article/details/79993186