2011年1月9日 星期日

[Linux module program] 1. Hello World

編寫 hello.c 如下



##include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>

static int __init hello_init(void)
{
    printk(KERN_INFO "Hello world \n");

    return 0;
}

static void __exit hello_exit(void)
{
    printk(KERN_INFO "Goodbye, world \n");
}

module_init(hello_init);
module_exit(hello_exit);


編寫 Makefile 如下



obj-m += hello.o

all:
        make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
        make -C /lib/modules/$(shell uname -r)/build M=$(PwD) clean


PS: 請注意 make 前面為tab 而非空白

--
編譯前的準備:
1.  安裝所需程式:
     切換身份為 root, 執行
     yum install yum-utils
     yum install rpmdevtools
     yum install redhat-rpm-config
     yum install xmlto asciidoc elfutils-devel binutils-devel python-devel perl perl-ExtUtils-Embed

2.  Fedora 的 kernel source code
     (1) 先用指令 "uname -a" 查看 kernel 版本
           2.6.35.6-45.fc14.i686

     (2) 下載 kernel source rpm 檔
          http://download.fedora.redhat.com/pub/fedora/linux/releases/
          選擇 Fedora 的版本, 如 Fedora 14
          http://download.fedora.redhat.com/pub/fedora/linux/releases/14/Fedora/source/SRPMS/
         檔案:  kernel-2.6.35.6-45.fc14.src.rpm

     (3) 執行指令
          rpm -ivh kernel-2.6.35.6-45.fc14.src.rpm

          過程中會看到訊息:
          warning: user mockbuild does not exist - using root
          warning: group mockbuild does not exist - using root
          可以加入使用者後再執行一次
          su -c "groupadd mockbuild"
          su -c "useradd mockbuild -g mockbuild"

          安裝完後 會在使用者目錄下產生:  ~/rpmbuild
          切換目錄到 " cd ~/rpmbuild/SPEC"
          執行: rpmbuild -bp --target=$(uname -m) kernel.spec

          接著source會產生在BUILD底下, 可以copy 到 /usr/src/kernels 下
          cp -fr ./rpmbuild/BUILD/kernel-2.6.35.fc14/linux-2.6.35.i686 /usr/src/kernels/2.6.35.6-45.fc14.i686

          並確認 /lib/modules/2.6.35.6-45.fc14.i686/build -> ../../../usr/src/kernels/2.6.35.6-45.fc14.i686

    (4) 編譯 kernel 
          cd /usr/src/kernels/2.6.35.6-45.fc14.i686
          make

-- 編譯 Hello world
   在同 helloworld.c / Makefile 目錄下打 make , 出現問題: 
   (1) 缺少了 generated/bounds.h 檔
        可在 kernel source 目錄下執行 "make prepare"
   (2) insmod error : 
        insmod: error inserting 'hello.ko': -1 Invalid module format
        可用 dmesg 查看原因: 
        hello: version magic '2.6.35.6 SMP mod_unload 686 ' should be '2.6.35.6-45.fc14.i686 SMP mod_unload 686 '
        這是因為 module 版本與 kernel 版本不同的關係
        在 kernel source ( ) 的 Makefile 定義了
              VERSION = 2
              PATCHLEVEL = 6 
              SUBLEVEL = 35
              EXTRAVERSION = .6
        可將 EXTRAVERSION = .6 改為 EXTRAVERSION = .6-45.fc14.i686

-- 執行 "insmod hello.ko"
    dmesg : 可以看到 "Hello world"
    執行 "rmmod hello"
    dmesg : 可以看到 "Goodbye, world"
   
        




沒有留言:

熱門文章