• Linux嵌入式 -- 内核简介(x86)


    0. 嵌入式系统

    以应用为中心,软硬件可裁剪,对功耗、对体积、对成本等都有严格要求的专用计算机系统。


    1.  linux体系结构



    2. 为什么 划分为 用户空间 和 内核控件 ? 

    分两级,内核和应用程序,使操作系统本身得到充分保护。

    通过 系统调用 和 硬件中断 能从用户空间 --> 内核空间。


    3. 内核架构



    4.内核代码



    5. 内核配置与编译  (以 ../arch/xx/configs 里的配置做参考 .config)

    A:  清除:清除临时文件、中间文件和配置文件.
    • make clean
    remove most generated files but keep the config
    • make mrproper
    remove all generated files + config files 
    • make distclean
    mrproper + remove editor backup and patch files

    B: 确定目标系统的软硬件配置情况,比如CPU的类型、网卡的型号,所需支持的网络协议等。

    C: 命令配置内核

    make config:基于文本模式的交互式配置。
    make menuconfig:基于文本模式的菜单型配置。(推荐使用)

    在括号中按“y”将这个项目编译进内核中,按“m”编译为模块,按“n”为不选择(按空格键也可在编译进内核、编译为模块和不编译三者间进行切换),按“h”将显示这个选项的帮助信息,按“Esc”键将返回到上层选单。

    (*) A.c ----> A.o -----> image   (编译连接)

    (Y)B.c ---->B.o ------>image

    (M)C.c----->C.o       (编译不连接)

    (N)D.c------>             (不编译)

    ( ) E.c ------>

    make oldconfig:使用已有的配置文件(.config),但是会询问新增的配置选项。
    make xconfig:图形化的配置(需安装图形化系统)。

    D:编译内核

    make zImage
    make bzImage
    区别:在X86平台,zImage只能用于小于512K的内核
    如需获取详细编译信息,可使用:
    make zImage V=1
    make bzImage V=1

    编译好的内核位于arch/<cpu>/boot/目录下 **

    E: 编译内核模块

     make modules

    F:  安装内核模块
    make modules_install
    将编译好的内核模块从内核源代码目录copy至/lib/modules下

    G: 制作init ramdisk
    mkinitrd initrd-$version $version
    例:
    mkinitrd initrd-2.6.29  2.6.29
    $version 可以通过查询/lib/modules下的目录得到

    H: 内核安装(X86)

    1、cp arch/x86/boot/bzImage    /boot/vmlinuz-$version
    2、cp $initrd /boot/
    3、修改/etc/grub.conf 或者 /etc/lilo.conf
    ** $version 为所编译的内核版本号**



    6. 内核模块开发

    内核模块具有如下特点:
    • 模块本身并不被编译进内核文件(zImage或者bzImage)
    • 可以根据需求,在内核运行期间动态的安装或卸载。

    实例: hello 

    #include<linux/init.h>
    #include<linux/module.h>
    
    MODULE_LICENSE("GPL");
    MODULE_AUTHOR("lisi");
    MODULE_DESCRIPTION("hello world module");
    MODULE_ALIAS("a simple module");
    
    static char *name = "wangwu";
    static int age = 23;
    module_param(age, int, S_IRUGO);
    module_param(name, charp, S_IRUGO);
    
    static int hello_init(void)
    {
        printk("Hello world! 
    ");
    	printk("Name: %s, Age: %d 
    ", name, age);
        return 0;
    }
    
    static void hello_exit(void)
    {
        printk("Goodbye world! 
    ");
    }
    
    module_init(hello_init);
    module_exit(hello_exit);


    模块编译 Makefile

    ifneq ($(KERNELRELEASE),)
    obj-m :=hello.o
    else
    KDIR := /lib/modules/3.5.0-17-generic/build
    all: 
    	make -C $(KDIR) M=$(PWD) modules
    clean:
    	rm -f *.ok *.o *.mod.o *.mod.c *.symvers
    endif


    与应用程序的区别

    对比应用程序,内核模块具有以下不同:应用程序是从头(main)到尾执行任务,执行结束后从内存中消失。内核模块则是先在内核中注册自己以便服务于将来的某个请求,然后它的初始化函数结束,此时模块仍然存在于内核中,直到卸载函数被调用,模块才从内核中消失。


    模块安装与卸载

    加载 insmod (insmod hello.ko)
    卸载 rmmod (rmmod hello)
    查看 lsmod 
    加载 modprobe (modprobe hello)
    modprobe 如同 insmod, 也是加载一个模块到内核。它的不同之处在于它会根据文件/lib/modules/<$version>/modules.dep来查看要加载的模块, 看它是否还依赖于其他模块,如果是,modprobe 会首先找到这些模块, 把它们先加载到内核。

    模块参数

    通过宏module_param指定模块参数,模块参数用于在加载模块时传递参数给模块。
    module_param(name,type,perm)
    name是模块参数的名称,type是这个参数的类型, perm是模块参数的访问权限。

    type常见值:
    bool:布尔型 int:整型 charp:字符串型

    perm 常见值:
    S_IRUGO:任何用户都对/sys/module中出现的该参数具有读权限
    S_IWUSR:允许root用户修改/sys/module中出现的该参数


    内核符号的导出使用:
    EXPORT_SYMBOL(符号名)
    EXPORT_SYMBOL_GPL(符号名)
    其中EXPORT_SYMBOL_GPL只能用于包含GPL许可证的模块。


    常见问题: 版本不匹配

    解决方法:
    1、使用 modprobe  --force-modversion 强行插入
    2、确保编译内核模块时,所依赖的内核代码本等同于当前正在运行的内核。
    **可通过uname –r 察看当前运行的内核版本**


    Printk允许根据严重程度,通过附加不同的“优先级”来对消息分类。

    优先级递减的顺序分别是:
    KERN_EMERG                   “<0>” 用于紧急消息,常常是那些崩溃前的消息。
    KERN_ALERT                 “<1>”  需要立刻行动的消息。
    KERN_CRIT                “<2>” 严重情况。
    KERN_ERR                   “<3>”  错误情况。

    KERN_WARNING              “<4>” 有问题的警告
     KERN_NOTICE             “<5>” 正常情况,但是仍然值得注意
     KERN_INFO                 “<6>” 信息型消息
     KERN_DEBUG                “<7>”用作调试消息

    没有指定优先级的printk默认使用DEFAULT_MESSAGE_LOGLEVEL优先级,它是一个在kernel/printk.c中定义的整数。

    #define DEFAULT_MESSAGE_LOGLEVEL 4 
    /* KERN_WARNING */


  • 相关阅读:
    第一周软件测试
    第八周
    第七
    安卓第六周作业
    安卓第五周
    第四周作业
    Jsp第十次作业
    Jsp第九次作业(带验证码的email)
    Jsp第八次作业
    Jsp第七次作业email
  • 原文地址:https://www.cnblogs.com/xj626852095/p/3648254.html
Copyright © 2020-2023  润新知