2009年12月15日 星期二

如何利用kvm/qemu練習linux module


"如何利用kvm/qemu練習linux module"將介紹如何編譯一個bzImage在kvm上面執行,我們將掛上一個initramfs當我們的root filesystem,除了沒有實體的裝置以外,其實可以看成一個embedded linux了。我也是利用這種方式撰寫module的文章,因為module一寫不好,kernel就會crash了,透過vm,就不怕kernel crash了。
編譯kernel
brook@ubuntu:~$ mkdir linux
brook@ubuntu:~$ cd linux/
brook@ubuntu:~/linux$ apt-get source linux-image-2.6.31-16-generic
Reading package lists... Done
Building dependency tree       
Reading state information... Done
NOTICE: 'linux' packaging is maintained in the 'Git' version control system at:
http://kernel.ubuntu.com/git-repos/ubuntu/ubuntu-karmic.git
Need to get 81.0MB of source archives.
Get:1 http://tw.archive.ubuntu.com karmic-updates/main linux 2.6.31-16.53 (dsc) [3,781B]
0% [Waiting for headers]    
Fetched 81.0MB in 3min 29s (387kB/s)
gpgv: Signature made Tue 08 Dec 2009 11:50:10 AM CST using DSA key ID 17063E6D
gpgv: Can't check signature: public key not found
dpkg-source: warning: failed to verify signature on ./linux_2.6.31-16.53.dsc
dpkg-source: info: extracting linux in linux-2.6.31
dpkg-source: info: unpacking linux_2.6.31.orig.tar.gz
dpkg-source: info: applying linux_2.6.31-16.53.diff.gz
brook@ubuntu:~/linux$ cd linux-2.6.31
brook@ubuntu:~/linux/linux-2.6.31$ cp /boot/config-2.6.31-16-generic .config
brook@ubuntu:~/linux/linux-2.6.31$ make oldconfig
brook@ubuntu:~/linux/linux-2.6.31$ make menuconfig

接下來要設定我們的initramfs的目錄,先make menuconfig,接著選"General setup" -> "Initramfs source file(s)",接著輸入目錄"/home/brook/linux/rootfs",注意該選項的上一個選項"Initial RAM ilesystem and RAM disk (initramfs/initrd) support"有被enabled。如果要使用的是initrd則"Initramfs source file(s)"就留空白,使用initrd的好處是,initrd有任何改變都不需要重新compile kernel。

rootfs的基本設定
brook@ubuntu:~/linux$ mkdir rootfs
brook@ubuntu:~/linux$ cd rootfs
brook@ubuntu:~/linux/rootfs$ mkdir dev
brook@ubuntu:~/linux/rootfs$ mkdir tmp
brook@ubuntu:~/linux/rootfs$ mkdir bin
brook@ubuntu:~/linux/rootfs$ mkdir sbin
brook@ubuntu:~/linux/rootfs$ mkdir etc
brook@ubuntu:~/linux/rootfs$ mkdir lib
brook@ubuntu:~/linux/rootfs$ mkdir proc
brook@ubuntu:~/linux/rootfs$ mkdir sys
brook@ubuntu:~/linux/rootfs$ mkdir usr
brook@ubuntu:~/linux/rootfs$ apt-get install busybox-static
brook@ubuntu:~/linux/rootfs$ cp /bin/busybox bin
brook@ubuntu:~/linux/rootfs$ cd bin
brook@ubuntu:~/linux/rootfs/bin$ ln -s busybox -s mkdir
brook@ubuntu:~/linux/rootfs/bin$ ln -s busybox -s mknod
brook@ubuntu:~/linux/rootfs/bin$ ln -s busybox -s mount
brook@ubuntu:~/linux/rootfs/bin$ ln -s busybox -s rm
brook@ubuntu:~/linux/rootfs/bin$ ln -s busybox -s sh
brook@ubuntu:~/linux/rootfs/bin$ cd ../sbin
brook@ubuntu:~/linux/rootfs/sbin$ ln -s ../busybox -s init
brook@ubuntu:~/linux/rootfs/sbin$ ln -s ../busybox -s mdev
brook@ubuntu:~/linux/rootfs/$ find . |cpio -H newc -o > ../initrd

如果使用的是initrd則需要用cpio壓縮這個目錄,如果是initramfs就不用最後一個指令了。

接著當然還要寫一下init script,負責開機後的一些基本設定,其內容如下
#!/bin/sh
#Mount things needed by this script
mount -t tmpfs -o size=64k,mode=0755 tmpfs /dev
mkdir /dev/pts
mount -t devpts devpts /dev/pts
/bin/mount -t proc proc /proc
/bin/mount -t sysfs sysfs /sys

#Create all the symlinks to /bin/busybox
/bin/busybox --install -s

#Create device nodes
echo /sbin/mdev > /proc/sys/kernel/hotplug
/sbin/mdev -s

exec /sbin/init
最後make bzImage即可。

接著執行kvm/qemu吧
brook@ubuntu:~/linux/linux-2.6.31$ kvm -no-acpi -kernel arch/x86_64/boot/bzImage -net nic,model=pcnet -net tap,ifname=tap0,script=no

如果是initrd則需要多一個參數給kvm/qemu。
brook@ubuntu:~/linux/linux-2.6.31$ kvm -no-acpi -kernel arch/x86_64/boot/bzImage -initrd /home/brook/initrd -net nic,model=pcnet -net tap,ifname=tap0,script=no



8 則留言:

  1. 在target board上面

    echo "g" > /prco/sysrq-trigger

    就可以中斷執行進入gdb



    更多訊息請參考

    Documentation/sysrq.txt




    回覆刪除
  2. Kernel hacking --->
    [*]Write protect kernel read-only data structures 取消此项[ ],此项可能導致kgdb出现問題

    回覆刪除
  3. 對於initrd的建立,Linux kernel提供一個整合性的工具,可一次處理目錄與檔案的封裝。gen_init_cpio

    回覆刪除
  4. 當我透過nfs想從qemu(guest)去mount我的ubuntu時,卻發生
    # mount -t nfs 192.168.12.1:/home/brook/src /mnt
    svc: failed to register lockdv1 RPC service (errno 111).
    mount: mounting 192.168.12.1:/home/brook/src on /mnt failed: Connection refused


    解決方式:
    加上option "nolock"

    # mount -t nfs -o nolock 192.168.12.1:/home/brook/src /mnt
    # df
    Filesystem 1K-blocks Used Available Use% Mounted on
    tmpfs 64 0 64 0% /dev
    192.168.12.1:/home/brook/src/
    54720576 38537280 13403648 74% /mnt

    回覆刪除
  5. 今天在build busybox-1.19.4發生以下錯誤
    /usr/include/mtd/ubi-user.h:412:3: error: conflicting types for ‘__packed’
    /usr/include/mtd/ubi-user.h:313:3: note: previous declaration of ‘__packed’ was here
    make[1]: *** [miscutils/ubi_tools.o] Error 1
    make: *** [miscutils] Error 2
    解決方式就是移除
    Miscellaneous Utilities底下所有掉所有和ubi相關選項


    參考網址:
    LFS:Busybox编译、建立文件系统

    回覆刪除
  6. On 64 bit x86 machines, if a 32 bit Busybox binary needs to be built, gcc and ld need to be used with -m32 option. This -m32 option for gcc and ld can be provided in the CFLAGS and LDFLAGS parameters to make at the command line as follows:

    make CFLAGS="-m32" LDFLAGS="-m32"

    回覆刪除
  7. 作者已經移除這則留言。

    回覆刪除
  8. for build 32bit kernel on 64bit machine, please use

    cp /boot/config-3.8.0-35-generic .config
    make ARCH=i386 olddefconfig
    make ARCH=i386 all


    This ends up calling gcc with -m32 and so on

    回覆刪除

熱門文章