- 論壇徽章:
- 0
|
一個(gè)簡(jiǎn)單的內(nèi)核加載的實(shí)驗(yàn),也折騰了不少的時(shí)間。轉(zhuǎn)載網(wǎng)上找的一篇文章,大家分享一下。學(xué)習(xí)一下人家的學(xué)習(xí)方法和思路,會(huì)有些幫助的。
內(nèi)核編程入門(mén),就以最為簡(jiǎn)單的hello.c為例。 環(huán)境:Redhat 9.0,內(nèi)核版本2.4.20-8。 雖然現(xiàn)在2.6.x的內(nèi)核很早就就發(fā)布了,但是畢竟很多公司還在使用2.4.x的內(nèi)核。作為新手,從2.4.x的內(nèi)核入手是可行的。原因有如下幾條: (1)2.4.x比較成熟?赡苣龅降慕^大多數(shù)問(wèn)題,網(wǎng)上都有解決方案。在這個(gè)過(guò)程中,您能夠節(jié)省大量的時(shí)間,同時(shí)還能夠?qū)Ρ染W(wǎng)上的解決方案,加深認(rèn)識(shí),總結(jié)解決問(wèn)題的方法,調(diào)整自己的學(xué)習(xí)方法和思路。 (2)事物的發(fā)展總不可能是一蹴而就的。了解發(fā)展的歷程,對(duì)深入理解問(wèn)題有很大的好處。所以在2.4.x的內(nèi)核的基礎(chǔ)上學(xué)習(xí)2.6.x的內(nèi)核,就能夠體會(huì)到2.6.x的內(nèi)核在哪些方面要出色,或?yàn)槭裁匆扇∵@種改進(jìn)技術(shù)。相信理論清楚了,實(shí)時(shí)2.6.x的內(nèi)核也會(huì)容易上手。 下面總結(jié)了第一個(gè)內(nèi)核程式hello.c的學(xué)習(xí)過(guò)程。(一)第一階段:盡量簡(jiǎn)單/** hello.c*/#define MODULE#include linux/module.h>int init_module(void){ printk("Hello World!\n"); return 0;}void cleanup_module(void){ printk("Goodbye!\n");}執(zhí)行,出現(xiàn)錯(cuò)誤一:[root@lqm drivers]# gcc -c hello.c[root@lqm drivers]# insmod hello.ohello.o: kernel-module version mismatch hello.o was compiled for kernel version 2.4.20 while this kernel is version 2.4.20-8. 這是因?yàn)閮?nèi)核源代碼版本和編譯器版本不一致造成的。(1)編譯器版本/usr/include/linux/version.h#define UTS_RELEASE "2.4.20"#define LINUX_VERSION_CODE 132116#define KERNEL_VERSION(a,b,c) (((a) 16) + ((b) 8) + (c))(2)內(nèi)核源代碼版本/usr/src/linux-2.4.20-8/include/linux/version.h/usr/src/linux-2.4.20-8/include/linux[root@lqm linux]# cat version.h#include linux/rhconfig.h>#if defined(__module__smp)#define UTS_RELEASE "2.4.20-8smp"#elif defined(__module__BOOT)#define UTS_RELEASE "2.4.20-8BOOT"#elif defined(__module__bigmem)#define UTS_RELEASE "2.4.20-8bigmem"#else#define UTS_RELEASE "2.4.20-8"#endif#define LINUX_VERSION_CODE 132116#define KERNEL_VERSION(a,b,c) (((a) 16) + ((b) 8) + (c)) 能夠采取修改編譯器版本號(hào)和內(nèi)核源代碼版本號(hào)一致的辦法來(lái)解決這個(gè)問(wèn)題,即修改/usr/include/linux/version.h中 #define UTS_RELEASE "2.4.20"為 #define UTS_RELEASE "2.4.20-8"執(zhí)行,出現(xiàn)錯(cuò)誤二:[root@lqm drivers]# gcc -c hello.c[root@lqm drivers]# insmod hello.oWarning: loading hello.o will taint the kernel: no license See http://www.tux.org/lkml/#export-tainted for information about tainted modulesModule hello loaded, with warnings[root@lqm drivers]# tail -n 1 /var/log/messagesJan 30 12:02:08 lqm kernel: Hello 也就是說(shuō)出現(xiàn)了no license的警告。GNU的軟件需要有GPL,所以修改源代碼如下:/** hello.c*/#define MODULE#include linux/module.h>MODULE_LICENSE("GPL");int init_module(void){ printk("Hello World!\n"); return 0;}void cleanup_module(void){ printk("Goodbye!\n");} 這時(shí)沒(méi)有錯(cuò)誤了。寫(xiě)了一個(gè)腳本,測(cè)試流程自動(dòng)化:#!/bin/bashgcc -c hello.csleep 1insmod hello.o && echo -e "Instal module - hello.o\n"sleep 1tail -n 1 /var/log/messageslsmod | grep "hello" && echo -e "Module hello has instaled\n"rmmod hello && echo -e "Remove module - hello\n"sleep 1tail -n 1 /var/log/messageslsmod | grep "hello" || echo "Module hello has removed"執(zhí)行結(jié)果如下:[root@lqm hello]# ./runInstal module - hello.o Jan 30 13:31:29 lqm kernel: Hello World! hello 748 0 (unused) Module hello has instaled Remove module - hello Jan 30 13:31:30 lqm kernel: Goodbye! Module hello has removed(二)第二階段:完善,深入一點(diǎn)/** hello.c*/#ifndef __KERNEL__ #define __KERNEL__#endif#ifndef MODULE #define MODULE#endif#include linux/kernel.h> /*printk*/#include linux/module.h>MODULE_LICENSE("GPL");static int init_module(void){ printk("Hello, world!\n"); return 0;}static void cleanup_module(void){ printk("Goodbye!\n");}寫(xiě)Makefile文檔如下:# Kernel Programming# Shandong University, Linqingmin# The path of kernel source codeINCLUDEDIR = /usr/src/linux-2.4.20-8/include/# CompilerCC = gcc# OptionsCFLAGS = -D__KERNEL__ -DMODULE -O -Wall -I$(INCLUDEDIR)# TargetOBJS = hello.oall: $(OBJS)$(OBJS): hello.c /usr/include/linux/version.h $(CC) $(CFLAGS) -c $install: insmod $(OBJS)uninstall: rmmod hello.PHONY: cleanclean: rm -f *.o 寫(xiě)Makefile時(shí)應(yīng)該注意,不要用空格來(lái)代替。否則會(huì)出現(xiàn)錯(cuò)誤:missing separator. Stop.修改執(zhí)行腳本run:#!/bin/bash# The first stepmake && make install && echo -e "Instal module - hello.o\n"sleep 1tail -n 1 /var/log/messageslsmod | grep "hello" && echo -e "Module hello has instaled\n"# The second stepmake uninstall && echo -e "Remove module - hello\n"sleep 1tail -n 1 /var/log/messageslsmod | grep "hello" || echo "Module hello has removed"# The last stepmake clean
本文來(lái)自ChinaUnix博客,如果查看原文請(qǐng)點(diǎn):http://blog.chinaunix.net/u2/83134/showart_1724300.html |
|