linux内核源码编译,制作可启动内核镜像

http://leslie-chu.blog.163.com/blog/static/19986324320121411230520/



linux内核源码编译,制作可启动内核镜像 - Leslie Chu - Leslie Chu
   
      linux社区有一个项目叫LFS,帮助linux爱好者自己一步步制作一个linux系统,设置可以加入一些特性做成一个和Ubuntu、SUSE不同的发行版。
        不过,在这之前我先试试编译内核源码,制作一个可启动的内核镜像。
第一步,下载linux内核源码,网址:http://www.kernel.org/
            $wget -r  
http://www.kernel.org/pub/linux/kernel/v3.0/testing/linux-3.2-rc5.tar.bz2

第二步,解压linux-3.2.0-rc5.tar.gz
            $cd ~;
            $tar -xzvf linux-3.2.0-rc5.tar.gz
            $cp -r linux-3.2.0-rc5 /usr/src/kernels/
            $cd /usr/src/kernels/linux-3.2.0-rc5

第三步,配置.config并编译
            $make menuconfig
            $make
            $make modules_install

第四步,设置boot
            $cp ./boot/arch/i386/bzImage /boot/vmlinuz-3.2.0
            $cp System.map /boot/System.map-3.2.0
            $cd /boot
            $mkinitrd initramfs-3.2.0-rc5.img 3.2.0

第五步,设置menu.lst(注意备份)
(添加内容):
title Leslie (3.2.0-rc5)
    root(hd0,6)
    kernel /vmlinuz-3.2.0 ro root=UUID=9da94500-35bc-430c-8502-12913da21a52 rd_NO_LUKS rd_NO_LVM rd_NO_MD rd_NO_DM LANG=zh_CN.UTF-8 KEYTABLE=us nomodeset rhgb quiet
    initrd /initramfs-3.2.0-rc5.img

第六步,重启并选择Leslie启动
           $reboot
           .......
           $uname -r
===>    3.2.0 (说明是以最新内核启动的)

第七步,查看/lib/modules/3.2.0-rc5
          $ls -l /lib/modules/3.2.0-rc5
===>
lrwxrwxrwx  1 root root     31  2月  3 16:34 build -> /usr/src/linux-3.2-rc5
drwxr-xr-x 13 root root   4096  2月  3 18:06 kernel
-rw-r--r--  1 root root 616700  2月  3 18:07 modules.alias
-rw-r--r--  1 root root 605455  2月  3 18:07 modules.alias.bin
-rw-r--r--  1 root root   6635  2月  3 18:04 modules.builtin
-rw-r--r--  1 root root   8480  2月  3 18:07 modules.builtin.bin
-rw-r--r--  1 root root     69  2月  3 18:07 modules.ccwmap
-rw-r--r--  1 root root 248478  2月  3 18:07 modules.dep
-rw-r--r--  1 root root 358144  2月  3 18:07 modules.dep.bin
-rw-r--r--  1 root root    246  2月  3 18:07 modules.devname
-rw-r--r--  1 root root    889  2月  3 18:07 modules.ieee1394map
-rw-r--r--  1 root root    218  2月  3 18:07 modules.inputmap
-rw-r--r--  1 root root  15833  2月  3 18:07 modules.isapnpmap
-rw-r--r--  1 root root    307  2月  3 18:07 modules.ofmap
-rw-r--r--  1 root root  93563  2月  3 18:04 modules.order
-rw-r--r--  1 root root 382117  2月  3 18:07 modules.pcimap
-rw-r--r--  1 root root   1261  2月  3 18:07 modules.seriomap
-rw-r--r--  1 root root    131  2月  3 18:07 modules.softdep
-rw-r--r--  1 root root 231589  2月  3 18:07 modules.symbols
-rw-r--r--  1 root root 293542  2月  3 18:07 modules.symbols.bin
-rw-r--r--  1 root root 977951  2月  3 18:07 modules.usbmap
lrwxrwxrwx  1 root root     31  2月  3 18:04 source -> /usr/src/linux-3.2-rc5

第八步,修改代码,重新编译,查看特性。。。。。

      前面这张照片是我编译内核后用dmesg命令查看的信息,因为我在init/main.c文件的start_kernel函数入口加入了一些打印信息。因此,在CPU从自我模式进入保护模式时就需要调用此函数,从而打印我所设定的信息。这是很普通的操作,却是我学习内核的第一步。


http://leslie-chu.blog.163.com/blog/static/199863243201241225615710/?suggestedreading&wumii

以前编译过linux内核,但编译自定义模块一直失败,后来不了了之。这几天又拿起内核方面的资料看,查了点资料,竟然编译过去了,回头总结下,发现压根就是我自己不上心。
         周末有时间了,顺便做点笔记,吃了点兴国鱼丝,肚里有食要好好渡过漫漫长夜,明天醒来的早还可以看场电影吧。

         编译内核:

         编译内核,第一步肯定是下载内核源码树(www.kernel.org),然后解压到/usr/src目录(习惯)。
         配置内核编译,是执行命令make menuconfig,如果想用默认配置的话,就直接退出保存即可。
         编译内核执行命令make bzImage,生成的bzImage文件在arch/x86/boot/目录中。将此文件拷贝到/boot目录下并以vmlinuz开头命名。另外,把System.map拷贝到/boot目录重命名。
        编译、安装模块是执行命令make modules && make modules_install,执行后会在目录/lib/modules/下建立一个以内核版本号为目录名的目录,内核模块就在此目录下。
        在/boot目录下执行mkinitrd initramfs-3.2.0-rc5.img 3.2.0-rc5这里的3.2.0-rc5是我编译的内核版本号,也是/lib/modules/3.2.0-rc5目录名。

        总结:
         1. 下载内核文件,加压到/usr/src/;
         2. make menuconfig
         3. make bzImage
         4. make modules && make modules_install    
         5. cp arch/x86/boot/bzImage /boot/vmlinuz-3.2.0-rc5
         6. cp System.map /boot/System-3.2.0-rc5.map
         7. cd /boot && mkinitrd initramfs-3.2.0-rc5.img 3.2.0-rc5 (以3.2.0-rc5例)
         8. vim /boot/grub/grub.conf(可选)
         9. reboot
        
         编辑grub.conf(可选):

         default=1        (第一个启动title是0,这里默认以第二个title启动)
         timeout=5      (停留5秒)
         splashimage=(hd0,6)/grub/splash.xpm.gz  (grub的背景)
         hiddenmenu

         title Fedora (2.6.43.2-6.fc15.i686)     (系统本身内核)
                root (hd0,6)           (/boot所在分区)
                kernel /vmlinuz-2.6.43.2-6.fc15.i686 ro root=UUID=9da94500-35bc-430c-8502-12913da21a52 (如果/etc/fstab定义了LABEL,这里是root=LABEL=/,也可以是root=/dev/sda9)
                initrd /initramfs-2.6.43.2-6.fc15.i686.img   (系统内核镜像)

        title LeslieChu (3.2.0-rc5)
               root(hd0,6)
               kernel /vmlinuz-3.2.0-rc5 ro root=UUID=9da94500-35bc-430c-8502-12913da21a52 
               initrd /initramfs-3.2.0-rc5.img

        title Windows 7(Simple Life,Freely World!)
              rootnoverify (hd0,0)     (win7安装在第一块磁盘的第一个分区)
              chainloader +1

         GRUB命令(若没有配置/boot/grub/grub.conf):
              
启动时,按Enter进入grub引导界面,按c进入grub命令行环境。
              分两种情况,一种是/和/boot在一个分区,一种是/和/boot不在一个分区,同一个分区则路径以/boot开头。

              1.确定/boot所在分区
                 grub>find /boot/grub/stage1   或find /grub/stage1   (这里按TAB会自动提示)
                 输出:(hd0,6)
                 grub>root (hd0,6)                   (设置/boot所在分区)

              2.确定/所在分区或设备符或标签
                grub>cat /boot/grub/grub.conf  或cat /grub/grub.conf

              3.确定内核文件和内核选项
                grub>kernel /boot/vmliuz-3.2.0-rc5 ro root=UUID=asdfwa-s...
                或
                grub>kernel /vmlinuz-3.2.0-rc5 ro root=UUID=asdfasdfs....
                (这里表示/所在分区的方法很多,可以是标签root=LABEL=/,也可以是root=/dev/sda9)

              4.确定引导系统内核镜像
               grub>
initrd /boot/initramfs-3.2.0-rc5.img
               或
               grub>initrd /initramfs-3.2.0-rc5.img

              5.引导
              grub>boot
               
            编译自定义模块:

                 用新内核启动系统后,可以用uname -r来查看内核,系统只是更换了内核,其它部分是发行版本的事情,并没有其它区别。但是,如果新内核不支持某些特性,比如kvm,则kvm方面的功能无法使用。
                 假设有自定义模块firstmod.ko,源码文件是firstmod.c:

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


#define DRIVER_AUTHOR "LeslieChu"
#define DRIVER_DESC "test hello module"
#define VERSION "1.0.0"
#define ALIAS  "HeiMod"
#define LICENSE "GPL"

/*导出模块变量*/
int abc = 3;
int i = 0;
module_param(abc,int,S_IRUGO);

/*定义模块信息,通过modinfo查看*/
MODULE_LICENSE(LICENSE);
MODULE_AUTHOR(DRIVER_AUTHOR );        
MODULE_DESCRIPTION(DRIVER_DESC );    
MODULE_VERSION(VERSION);
MODULE_ALIAS(ALIAS);

/*加载模块*/
static int __init first_init (void)
{
    printk("the first mode insmod\n");
    for(i=0;i<abc;i++)
        printk("the i is : %d\n",i);
    return 0;
}

/*导出模块函数符号*/
static void haha(void)
{
    for(i=0;i<abc;i++)
    printk("+++++i=%d\n",i);
    }

/*卸载模块*/
static void __exit first_exit (void)
{
    printk("the first mode rmmod\n");
}

/*注册模块*/
module_init(first_init);
module_exit(first_exit);
EXPORT_SYMBOL(haha);  

             最简单的Makefile:
obj-m:=firstmod.o

             最简单的编译方法:
make -C /usr/src/linux-3.2.0-rc5/ M=`pwd` modules (在源码所在目录执行)

             稍复杂的Makefile:
obj-m:=firstmod.o
KDIR:=/lib/modules/3.2.0-rc5/build
PWD:=$(shell pwd)

default:
    make -C $(KDIR) M=$(PWD) modules
clean:
    rm -rf *.o  .cmd *.ko *.mod.c .tmp_versions *.order  *.sym*

             稍复杂的编译方法:make 

             查看模块firstmod.ko:
$modinfo firstmod.ko
filename:       firstmod.ko
alias:          HeiMod
version:        1.0.0
description:    test hello module
author:         LeslieChu
license:        GPL
srcversion:     FE2406F74135246FCAA271C
depends:        
vermagic:       3.2.0-rc5 SMP mod_unload 686 
parm:           abc:int

                  加载模块firstmod.ko:
$insmod firstmod.ko
$lsmod | grep firstmod
firstmod               12574  0
$dmesg | tail -10
.....
[11525.493829] the first mode insmod
[11525.493832] the i is : 0
[11525.493833] the i is : 1
[11525.493835] the i is : 2
.....

               卸载模块firstmod.ko:
$rmmod firstmod
$dmesg
[14436.331425] the first mode rmmod

               后续如果更改了内核代码,则重新编译、安装内核一次即可;如果自己写模块,则按照上面方法编译即可。模块的功能很强大,但我知道的就这么多,如果一个32位系统的模块,到了64位系统上能编译过吗?
              这将是下周我要面临的难题。
  • 0
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值