十天学Linux内核之第十天---总结篇(kconfig和Makefile & 讲不出再见)

原文:十天学Linux内核之第十天---总结篇(kconfig和Makefile & 讲不出再见)

  非常开心能够和大家一起分享这些,让我受益匪浅,感激之情也溢于言表,,code monkey的话少,没办法煽情了,,,,,,,冬天的风,吹得伤怀,倒叙往事,褪成空白~学校的人越来越少了,就像那年我们小年之后再回家的场景一样,到处荒芜,然而我们的激情却不褪去,依然狂躁在实验室凌晨两点半的星空里,也许今天又会是这样的一年,不一样的是身边的人变成学弟学妹了,而我们几个大三老家伙依然在,为自己喜欢的事情,为自己的梦想,为我们的相互陪伴而不断努力,这样才对得起我们的青春,对得起这些难忘的岁月~~

下面是我们的两次照片,去年过年前和今年临走时的,,贴出来大家分享一下,嘎嘎~再分享一张我的女神的照片(嘿嘿,,,,Thank you for your company.)

        

  既然是总结,那么最后一天我就和大家一起分享一下学习Linux内核的方法以及难点重点吧,希望各路大神多加补充以及讨论,互相学习。

   毫不夸张地说,Kconfig和Makefile是我们浏览内核代码时最为依仗的两个文件,分布在各目录下的Kconfig构成了一个分布式的内核配置数据库,每个Kconfig分别描述了所属目录源文件相关的内核配置菜单。基本上,Linux内核中每一个目录下边都会有一个Kconfig文件和一个Makefile文件。Kconfig和Makefile就是Linux Kernel迷宫里的地图。地图引导我们去认识一个城市,而Kconfig和Makefile则可以让我们了解一个Kernel目录下面的结构。我们每次浏览kernel寻找属于自己的那一段代码时,都应该首先看看目录下的这两个文件。

下面简要介绍一下Kconfig  

每个菜单项都有一个关键字标识,最常见的就是config。

语法:
config symbol

options
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->

symbol就是新的菜单项,options是在这个新的菜单项下的属性和选项

其中options部分有:

1、类型定义:
每个config菜单项都要有类型定义,bool:布尔类型, tristate三态:内建、模块、移除, string:字符串, hex:十六进制, integer:整型

2、依赖型定义depends on或requires
指此菜单的出现是否依赖于另一个定义

3、帮助性定义
只是增加帮助用关键字help或---help---
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->

 

Kconfig文件的基本要素:

1.config条目(entry)

 config是关键字,表示一个配置选项的开始;紧跟着的TMPFS_POSIX_ACL是配置选项的名称,省略了前缀"CONFIG_"

    bool表示变量类型,即"CONFIG_ TMPFS_POSIX_ACL "的类型,有5种类型:bool、tristate、string、hex和int,其中tristate和string是基本的类型

              bool变量的值:    y和n

              tristate变量的值:y、n和m

              string变量的值:  字符串

    bool之后的字符串“Tmpfs POSIX Access Control Lists”是提示信息,在配置界面中上下移动光标选中它时,就可以通过按空格或回车键来设置

CONFIG_ TMPFS_POSIX_ACL的值

    depends on:表示依赖于XXX,“depends on TMPFS”表示只有当TMPFS配置选项被选中时,当前配置选项的提示信息才会出现,才能设置当前配置选项

2.menu条目

   menu条目用于生成菜单,其格式如下:

         menu "Floating poing emulation"

         config FPE_NWFPE

         ..............

         config FPE_NWFPE_XP

         .............

         endmenu

   menu之后的Floating poing emulation是菜单名,menu和endmenu间有很多config条目,在配置界面中如下所示:

         Floating poing emulation--->

                       [] FPE_NWFPE

                       [] FPE_NWFPE_XP

3.choice条目

   choice条目将多个类似的配置选项组合在一起,供用户单选或多选

       choice

             prompt "ARM system type"

             default ARCH_VERSATILE

 

             config ARCH_AAEC2000

                  .........

             config ARCH_REALVIEW

                  .........

        endchoice

      prompt "ARM system type"给出提示信息“ARM system type”,光标选中后回车进入就可以看到多个config条目定义的配置选项 choice条目中定义的变量只有bool和tristate

4.comment条目

   comment条目用于定义一些帮助信息,出现在界面的第一行,如在arch/arm/Kconifg中有如下代码:

menu "Floating point emulation"

comment "At least one emulation must be selected"

config FPE_NWFPE

.........                                                                               

config FPE_NWFPE_XP

5.source条目

   source条目用于读取另一个Kconfig文件,如:

        source "net/Kconifg"

 

  介绍一下makefile

  Makefile可比Kconfig简略多了,内核的Makefile分为5个组成部分:

  • Makefile     最顶层的Makefile
  •  .config        内核的当前配置文档,编译时成为顶层Makefile的一部分
  • arch/$(ARCH)/Makefile    和体系结构相关的Makefile
  • Makefile.*      一些特定Makefile的规则
  • kbuild级别Makefile      各级目录下的大概约500个文档,编译时根据上层Makefile传下来的宏定义和其他编译规则,将源代码编译成模块或编入内核。顶层的Makefile文档读取.config文档的内容,并总体上负责build内核和模块。Arch Makefile则提供补充体系结构相关的信息。其中.config的内容是在make menuconfig的时候,通过Kconfig文档配置的结果。

  对Makefile函数,我们从初始化函数开始,针对某个子系统或某个驱动,内核使用subsys_initcall或module_init宏指定初始化函数。在drivers/usb/core/usb.c文件中,我们可以发现下面的代码:

940 subsys_initcall(usb_init);  //告诉我们usb_init是USB子系统真正的初始化函数,
941 module_exit(usb_exit);  //将是整个USB子系统的结束时的清理函数

为了研究USB子系统在内核中的实现,我们需要从usb_init函数开始看起,,,下面的代码求大神指教,不懂啊

865 static int __init usb_init(void)
866 {
867 int retval;
868 if (nousb) {
869 pr_info("%s: USB support disabled\n", usbcore_name);
870 return 0;
871 }
872
873 retval = ksuspend_usb_init();
874 if (retval)
875 goto out;
876 retval = bus_register(&usb_bus_type);
877 if (retval)
878 goto bus_register_failed;
879 retval = usb_host_init();
880 if (retval)
881 goto host_init_failed;
882 retval = usb_major_init();
883 if (retval)
884 goto major_init_failed;
885 retval = usb_register(&usbfs_driver);
886 if (retval)
887 goto driver_register_failed;
888 retval = usb_devio_init();
889 if (retval)
890 goto usb_devio_init_failed;
891 retval = usbfs_init();
892 if (retval)
893 goto fs_init_failed;
894 retval = usb_hub_init();
895 if (retval)
896 goto hub_init_failed;
897 retval = usb_register_device_driver(&usb_generic_driver, THIS_MODULE);
898 if (!retval)
899 goto out;
900
901 usb_hub_cleanup();
902 hub_init_failed:
903 usbfs_cleanup();
904 fs_init_failed:
905 usb_devio_cleanup();
906 usb_devio_init_failed:
907 usb_deregister(&usbfs_driver);
908 driver_register_failed:
909 usb_major_cleanup();
910 major_init_failed:
911 usb_host_cleanup();
912 host_init_failed:
913 bus_unregister(&usb_bus_type);
914 bus_register_failed:
915 ksuspend_usb_cleanup();
916 out:
917 return retval;
918 }

 

  API感想(此处我也不懂,API的概念我脑海中还没建立,贴出来大家一起分享注意一下)

  “比起知道你所用技术的重要性,成为某一个特别领域的专家是不重要的。知道某一个具体API调用一点好处都没有,当你需要他的时候只要查询下就好了。”这句话源于我看到的一篇翻译过来的博客。我想强调的就是,这句话针应用型编程再合适不过,但是内核API就不完全如此。

内核相当复杂,学习起来很不容易,但是当你学习到一定程度,你会发现,如果自己打算写内核代码,到最后要关注的仍然是API接口,只不过这些API绝大部分是跨平台的,满足可移植性。内核黑客基本上已经标准化、文档化了这些接口,你所要做的只是调用而已。当然,在使用的时候,最好对可移植性这一话题在内核中的编码约定烂熟于心,这样才会写出可移植性的代码。就像应用程序一样,可以使用开发商提供的动态库API,或者使用开源API。同样是调用API,不同点在于使用内核API要比使用应用API了解的东西要多出许多。

当你了解了操作系统的实现---这些实现可都是对应用程序的基础性支撑啊---你再去写应用程序的时候,应用程序中用到的多线程,定时器,同步锁机制等等等等,使用共享库API的时候,联系到操作系统,从而把对该API的文档描述同自己所了解到的这些方面在内核中的相应支撑性实现结合起来进行考虑,这会指导你选择使用哪一个API接口,选出效率最高的实现方式。对系统编程颇有了解的话,对应用编程不无益处,甚至可以说是大有好处。

 

  内核文档

  最后来说下相关的内核文档,内核代码中包含有大量的文档,这些文档对于学习理解内核有着不可估量的价值,记住,在任何时候,它们在我们心目中的地位都应该高于那些各式的内核参考书,只不过都是英文的了.不过还好,,嘎嘎,大一的时候就把英语六级过了,还是有点信心的,,不过过去两年了不知道自己的英语忘光了没有,下面是一些我们这些内核新人所应该阅读的文档。

  README这个文件首先简单介绍了Linux内核的背景,然后描述了如何配置和编译内核,最后还告诉我们出现问题时应该怎么办。

  Documentation/Changes这个文件给出了用来编译和使用内核所需要的最小软件包列表。

  Documentation/CodingStyle这个文件描述了内核首选的编码风格,所有代码都应该遵守里面定义的规范。

  Documentation/SubmittingPatches

  Documentation/SubmittingDrivers

  Documentation/SubmitChecklist            //这三个文件都是描述如何提交代码的,其中SubmittingPatches给出创建和提交补丁的过程,

  SubmittingDrivers描述了如何将 设备驱动提交给2.4、2.6等不同版本的内核树,SubmitChecklist则描述了提交代码之前需要check自己的代码应该遵守的某些事项。

  Documentation/stable_api_nonsense.txt这个文件解释了为什么内核没有一个稳定的内部API(到用户空间的接口——系统调用——是稳定的),它对于理解Linux的开发哲学至关重要,对于将开发平台从其他操作系统转移到Linux的开发者来说也很重要。

  Documentation/stable_kernel_rules.txt解释了稳定版内核(stable releases)发布的规则,以及如何将补丁提交给这些版本。

  Documentation/SecurityBugs内核开发者对安全性问题非常关注,如果你认为自己发现了这样的问题,可以根据这个文件中给出的联系方式提交bug,以便能够尽可能快的解决这个问题。

  Documentation/kernel-docs.txt这个文件列举了很多内核相关的文档和书籍,里面不乏经典之作。

  Documentation/applying-patches.txt这个文件回答了如何为内核打补丁。

  Documentation/bug-hunting这个文件是有关寻找、提交、修正bug的。

  Documentation/HOWTO这个文件将指导你如何成为一名内核开发者,并且学会如何同内核开发社区合作。它尽可能不包括任何关于内核编程的技术细节,但会给你指引一条获得这些知识的正确途径。

 

  小结

  最后一天没有说到一些具体的关于内核的知识,只是想重点分享一下kconfig和Makefile,这对学习内核来说至关重要,,当然了,上述提到的也是看了好多大牛的文章以及查阅了一些相关知识,大家可以参考一下一篇文章,具体讲了这些,我把链接附在下面:http://blog.chinaunix.net/uid-26258259-id-3783679.html  不知不觉这一系列的文章就要结束了,自己也要好好整理这些天所欠缺的,,非常感谢期间有些读者对我的支持,很开心和你们分享这些,,接下来要开始新的生活了,,但是我们的学习仍将继续,我们的激情不会褪去,我们的梦想我们的青春永恒~~

 

  版权所有,转载请注明转载地址:http://www.cnblogs.com/lihuidashen/p/4257007.html

时间: 2024-09-03 07:18:20

十天学Linux内核之第十天---总结篇(kconfig和Makefile & 讲不出再见)的相关文章

十天学Linux内核之第六天---调度和内核同步

原文:十天学Linux内核之第六天---调度和内核同步 心情大好,昨晚我们实验室老大和我们聊了好久,作为已经在实验室待了快两年的大三工科男来说,老师让我们不要成为那种技术狗,代码工,说多了都是泪啊,,不过我们的激情依旧不变,老师帮我们组好了队伍,着手参加明年的全国大赛,说起来我们学校历史上也就又一次拿国一的,去了一次人民大会堂领奖,可以说老大是对我们寄予厚望,以后我会专攻仪器仪表类的题目,激情不灭,梦想不息,不过最近一段时间还是会继续更新Linux内核,总之,继续加油~ Linux2.6版本中的

十天学Linux内核之第一天---内核探索工具类

原文:十天学Linux内核之第一天---内核探索工具类 寒假闲下来了,可以尽情的做自己喜欢的事情,专心待在实验室里燥起来了,因为大二的时候接触过Linux,只是关于内核方面确实是不好懂,所以十天的时间里还是希望能够补充一下Linux内核相关知识,接下来继续待在实验室里想总结一下Linux内核编程,十天肯定完全掌握不了Linux内核,这里我也只是把自己认为不是很好懂并且很重要的难点疑点写出来,和大家一起分享,希望大家改正互相学习. Linux的具体概述这里就不多说了,今天主要讲的是Linux内核中

十天学Linux内核之第四天---如何处理输入输出操作

原文:十天学Linux内核之第四天---如何处理输入输出操作 真的是悲喜交加呀,本来这个寒假早上8点都去练车,两个小时之后再来实验室陪伴Linux内核,但是今天教练说没名额考试了,好纠结,不过想想就可以睡懒觉了,哈哈,自从大三寒假以来还没睡过懒觉呢,现在也有更多的时间来分享自己学习Linux内核的感受,前几天觉得就是自己也有些不懂的,相信大家看了也是很模糊,以后我会标志出来自己不懂的,希望大神们指教,也希望大家多多指点,共同攻克Linux内核,今天将讲到处理器是如何与其它设备进行交互的,内核又是

十天学Linux内核之第二天---进程

原文:十天学Linux内核之第二天---进程 都说这个主题不错,连我自己都觉得有点过大了,不过我想我还是得坚持下去,努力在有限的时间里学习到Linux内核的奥秘,也希望大家多指点,让我更有进步.今天讲的全是进程,这点在大二的时候就困惑了我,结果那个时候我就止步不前了,这里主要讲的是为何引入进程.进程在Linux空间是如何实现的,并且描述了所有与进程执行相关的数据结构,最后还会讲到异常和中断等异步执行流程,它们是如何和Linux内核进行交互的,下面我就来具体介绍一下进程的奥妙. 首先我们要明确一个

十天学Linux内核之第九天---向内核添加代码

原文:十天学Linux内核之第九天---向内核添加代码 睡了个好觉,很晚才起,好久没有这么舒服过了,今天的任务不重,所以压力不大,呵呵,现在的天气真的好冷,不过实验室有空调,我还是喜欢待在这里,有一种不一样的感觉,在写了这么多天之后,自己有些不懂的页渐渐的豁然开朗了吗,而且也交到了一些朋友,真是相当开心啊.今天将介绍一下向内核中添加代码,一起来看看吧~ 先来熟悉一下文件系统,通过/dev可以访问Linux的设备,我们以men设备驱动程序为例来看看随机数是如何产生的,源代码在dirvers/cha

十天学Linux内核之第七天---电源开和关时都发生了什么

原文:十天学Linux内核之第七天---电源开和关时都发生了什么 说实话感觉自己快写不下去了,其一是有些勉强跟不上来,其二是感觉自己越写越差,刚开始可能是新鲜感以及很多读者的鼓励,现在就是想快点完成自己制定的任务,不过总有几个读者给自己鼓励,很欣慰的事情,不多感慨了,加紧时间多多去探索吧,今天要去描述的是电源开和关时都发生了什么,一起去看看吧~~ bootloader引导装入程序将内核映像加载到内存并处理控制权传送到内核后在内核引导时每个子系统都必须要初始化,我们根据实际执行的线性顺序跟踪内核的

十天学Linux内核之第五天---有关Linux文件系统实现的问题

原文:十天学Linux内核之第五天---有关Linux文件系统实现的问题 有时间睡懒觉了,却还是五点多醒了,不过一直躺倒九点多才算起来,昨晚一直在弄飞凌的嵌入式开发板,有些问题没解决,自己电脑系统的问题,虽然Win10发布了,,但我还是好喜欢XP呀,好想回家用用家里的XP来玩玩这块板子,不知不觉也第五天了,感觉代码都有些模糊,连自己都不是很清楚了,担心现在分享起来比较困惑,各路大神多加批评呀,觉得渣渣的尽量指正出来,拉出来批评,今天还是来总结一下有关Linux文件系统的问题吧~ Linux的使用

十天学Linux内核之第八天---构建Linux内核

原文:十天学Linux内核之第八天---构建Linux内核 今天是腊八节,说好的女票要给我做的腊八粥就这样泡汤了,好伤心,好心酸呀,看来代码写久了真的是惹人烦滴,所以告诫各位技术男敲醒警钟,不要想我看齐,不然就只能和代码为伴了的~~话说没了腊八粥但还是有代码,还有各位读者的支持呀,所以得继续写下去,静下心来,完成Linux内核的学习,坚持,加油~ 到目前为止,我们已经认识了Linux内核子系统,也探究了系统的初始化过程,并且深入探索了start_kernel()函数,同样,了解内核映像的创建也是

十天学Linux内核之第三天---内存管理方式

原文:十天学Linux内核之第三天---内存管理方式 昨天分析的进程的代码让自己还在头昏目眩,脑子中这几天都是关于Linux内核的,对于自己出现的一些问题我会继续改正,希望和大家好好分享,共同进步.今天将会讲诉Linux如何追踪和管理用户空间进程的可用内存和内核的可用内存,还会讲到内核对内存分类的方式以及如何决定分配和释放内存,内存管理是应用程序通过软硬件协助来访问内存的一种方式,这里我们主要是介绍操作系统正常运行对内存的管理.插个话题,刚才和姐姐聊天,她快结婚了,说起了自己的初恋,可能是一句很