hello world驱动显示
前几篇博客中,我们实现了内核的移植,根文件系统的制作。
到此,操作系统就可以跑起来了。我们可以来尝试第一个简单的hello world。
初步了解
内核了解,我们将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]$
开发板上测试
关闭防火墙,我们用tftp命令将文件下载到开发板上。
~ >: ifconfig eth0 192.168.10.112
~ >: ping 192.168.10.8
PING 192.168.10.8 (192.168.10.8): 56 data bytes
64 bytes from 192.168.10.8: seq=0 ttl=128 time=3.837 ms
64 bytes from 192.168.10.8: seq=1 ttl=128 time=1.478 ms
^C
--- 192.168.10.8 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 1.478/2.657/3.837 ms
~ >: tftp -gr kernel_hello.ko 192.168.10.8
kernel_hello.ko 100% |*******************************| 21595 0:00:00 ETA
~ >: ls
apps info media stat
bin init mnt sys
data kernel_hello.ko opt tmp
dev lib proc usr
etc linuxrc root var
home logs sbin
~ >: lsmod
~ >: insmod kernel_hello.ko
kernel_hello: module license 'unspecified' taints kernel.
Disabling lock debugging due to kernel taint
Hello, LingYun IoT Studio!
~ >: insmod kernel_hello.ko
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! ~ >:
- 这点非常重要,因为内核和用户空间的应用程序使用的是不同的保护地址空间。每个用户空间的进程都使用自己的虚拟地址空间,而内核则占用单独的地址空间 ↩
还没有评论,来说两句吧...