Linux内核Makefiles教程(一)

 Linux内核Makefiles 本教程描述了了Linux内核的Makefile是如何工作的。 1. 概述 Linux内核的Makefile包括五个部分。 Makefile <td style="width:373px;"> <p> 最上层Makefile </p> </td> .config <td style="width:373px;"> <p> 内核配置文件。 </p> </td> arch/$(ARCH)/Makefile <td style="width:373px;"> <p> CPU架构相关Makefile </p> </td> scripts/Makefile.* <td style="width:373px;"> <p> 对于所有Kbuild&nbsp;Makefile的公共方法。. </p> </td> kbuild Makefiles <td style="width:373px;"> <p> 有将近500个kbuild&nbsp;Makefiles。 </p> </td> 最上层Makefile读取.config文件。.config文件是由内核配置过程生成的。 最上级的Makefile负责生成linux的内核映象文件vmlinux和其它所有的模块。最上级Makefile递归地进入内核代码树的各级子目录分别执行子目录下的Makefile。究竟要进入哪些子目录是由内核配置阶段决定的,即配置在.cncfig文件中。最上级Makefile提定了一个路径为arch/$(ARCH)/Makefile的子目录Makefile。这个Makefile中定义了与处理器架构紧密相关的信息。 每一个子目录下面都有一个kbuild Makefile,这里都定义了一些makefile命令和变量可以被更下级的Makefile继承。Kbuild Makefile使用来自.config配置的信息生成各种文件列表用来构建内建的或者模块化的目标文件。Scripts/Makefile.*包括了很多被其它Makefile使用定义和规则。 2. 谁使用内核Makefile 内核Makefile的使用者可以大致分为四种。 用户(Userse) 这类使用者仅仅敲入一些命令,如“make menuconfig”或者“make”。他们很少会阅读甚修改内核Makefile和源代码文件。 一般开发者(Normal Developers) 一般开发者一般编写一些设备驱动程序,文件系统,网络协议。他们需要维护他们编写的代码涉及的子系统的kbuild Makefiles。为了工作地更有效率,他们甚至还需要对整个内核的Makefile有全局的把握,包括对kbuild的公共接口的详尽了解。 处理器架构开发者(Arch Developers) 这部分开发者关心与某个处理器架构紧密相关的代码部分,比如PC上最广泛使用的x86,以及IA64,还有ARM,Sparc,PowerPC,Alpha,s390,MIPS。Linux支持几百种处理器架构。从内核2.6.24开始,i386和x86_64合并为x86。 KBuild的开发者(KBuild Developers) KBuild的开发者就是维护内核构建系统的开发者,他们需要知道内核Makefile的各个方面。 —— 本篇教程主要面向第二类开发者和第三类开发者。即一般开发者和处理器体系架构开发者。 3. kbuild文件 大多数内核Makefile文件是kbuild Makefile文件,它们使用不同于一般make文件的kbuild语法。下面会介绍kbuild makefile的语法。Kbuild文件一般被命名为Mafile,但是也可以使用Kbuild名字。如果已经存在一个Makefile文件了,那么就只好用Kbuild名字了。 ...

July 6, 2012 · 1 min · kamus

三分钟Qt Quick入门

Qt Quick是一种设计用户界面的新方法。 在介绍Qt Quick之前,让我们先看一下现念的用户界面UI是什么样的。在桌面操作系统下,标准的按钮,文本框,窗体仍然能满足要求。但是这些千篇一律的灰色单调的控件渐渐让用户感到厌倦了。用户们更想看到平滑观感的,光泽的,动态的的用户界面。Qt Quick就是为了实现这些的目标。 Qt Quick包括两个部分。第一部分是QtDeclarative模块。这个模块负责把Qt Quick集成到Qt应用程序中。第二部分是一种界面描述语言:QML。使用QtDeclarative使得开发者能够在C++和QML之间共享数据对象,也可以把C++类插入到QML之中,等等。QML是个全新的语言,专门为设计用户界面设计,在其它的开发中也有用武之地。 迫不及待了吧。让我们看一个简单的例子: import Qt 4.6 Rectangle { width: 200 height: 200 Text { text: “hello! ykyi.net” font.pointSize: 10 font.bold: true anchors.centerIn: parent } } 读完这断代码,再尝试在Qt Creator中运行它。不用我多费口舌,你就恍然大悟了。每一个以大写字母开头的单词定义了一个新的对象。最外面的矩形则是主窗体,可以给它设置属性。比如anchors属性把Text限定在窗体的中央。这样,即使窗体放大了,文本仍然显示在窗体正中央。 前文,我有说过平滑观感的,光泽的,动态的的用户界面。那么Qt Quick怎么做到呢?简单!看看下面的代码,编辑Text的属性,设置rotation:NumberAnimation。不可思议的事情就发生了! rotation: NumberAnimation { to: 360; duration: 1500; running: true; repeat: true; } 现在,指定的文本疯狂的转动起来。我们已经看到在Qt Quick中开发有物资的界面是多么简单。我们所展示的只是Qt Quick特效的凤毛一角,最终能创造出什么样的奇幻效果只受限于你的想象力。 copyright ykyi.net

July 3, 2012 · 1 min · kamus

Barebox介绍

从裸机上电开始启动计算机的过程听起来是相当复杂的。在PC的世界里,BIOS统治这个领域已经几十年了。不过,哲学上讲任何世界都是从出生,到繁荣,再后到死亡的过程。BIOS的寿命也即将迎来终结。BIOS的掘墓者即是EFI。对于MAC用户来说,EFI的使用已经有好长一段时间了。而在嵌入式Linux的世界里,u-boot则在长时间里扮演着老大哥的角色。 U-boot,或者来自DENX的das U-boot提供了非常丰富的功能。如:网络,脚本,支持FLASH(这里的flash是存储方面的flash,而不是adobe的那个flash)。一般的嵌入式系统工程序师需要的工具,都提供好了。 还是那句话,对于万事万物,都是生生死死的过程啊。u-boot的功能越来越强大。催生了新的事物的诞生。它的名字就是:Barebox。 Barebox最开始被称之为:u-boot-v2,它是一个像u-boot一样野心勃勃的bootloader。不过Barebox更有Linux的味道一些。它的发展抛弃了u-boot而越来越像Linux。它有文件系统,有基本的shell,甚至还有与Linux近似的驱动模块。 Barebox的另一个创新即是,bootloader可以被构建成一个用户空间的应用程序。这样的好处是显而易近的,你可以更方便的开方和调试Barebox。 说了这么多,看看Barebox是个什么样子呢? uboot:/ uboot:/ ls . .. dev env 和Linux一样,dev目录夹下面放了系统的设备文件。比如,mem设备文件描述了计算机的内存。 再回到u-boot,它有一个特殊的命令:md。md命令可以查看内存的内容。对于Barebox,提供了同样的工具。不过这个工具是以一种POSIX的方式实现的:打开/dev/mem设备,lseek移动文件指针,read读出文件内容。这样的实现方式不仅仅提升了代码结构,它还使得md命令可以不需修改就应用到其它设备上,比如flash存诸器。 如果你想测试一下Barebox到底如何。你可以有两种方法。 第一:你可以下载Barebox的沙盒功能即把它构建成一个Linux的用户空间的应用。来自Barebox官方的解释是: Sandbox: If you develop features for Barebox, you can use the ‘sandbox’ target which compiles Barebox as a POSIX application in the Linux userspace: it can be started like a normal command and even has network access (tun/tap). Files from the local filesytem can be used to simulate devices. 如果你要为Barebox开发功能,你可以使用’沙盒’。这种方式把Barebox构建成一个Linux的用户空间程序。它像一般的命令一样,而且还有网络功能。来自文件系统的文件可以被用来模拟设备。 第二:不说你也知道,把Barebox安装到真真正正的硬件上吧!对于我,我就尝试过在PC机的一块旧式的主板上安装Barebox。 最后,Barebox的官方网站是: http://barebox.org/ ...

July 2, 2012 · 1 min · kamus

Linux如何设置IPv6地址

IPv6最终全面取待IPv6是不可逆的潮流。本文则讲一下在Linux下如何配置IPv6地址。当然本文假设你使用静态IP(不必是公共IPv6地址或公共IPv4地址,可以是私有IPv4地址)。本文不适用使用DHCP获取地址的情况。 首先,你要确保你使用的Linux的内核已经支持IPv6。当前比较新的Linux都已经内建IPv6了。 用root用户登录,运行: # lsmod | grep ipv6 看看系统有没有已经加载了IPv6模块。如果没有,尝试用以下命令加载: # /sbin/modprobe ipv6 第二,你需要有你的静态IP地址。 **IPv4地址如何转成IPv6地址呢?**如果你的IP是一个IPv4地址,那么可以换算得到IPv6的地址形式。比较简单的作法可以去到 http://grox.net/utils/ipv6.php。在左边的下拉列表中选择: IPv4 to 6to4 Address,在右边的编辑框中填上你的IPv4地址。点击: Calculate 则得到了你的IPv4地址的IPv6转化格式。 配置IPv6地址 一般的Linux发行版用 /etc/network/interfaces 文件配置网卡。如果没有这个文件,那么请注意 /etc/network 目录下其它文件或者目录。 假如要配置的Linux的静态IPv4地址是 192.168.1.10,这个IPv4地址转换成对应的IPv6地址则是 2002:c0a8:10a:: 。再提醒一下,上文提到过如何把IPv4地址转成IPv6地址。 网关的IPv4地址是 192.168.1.1,这个IPv4地址转成对应的IPv6的地址是:2002:c0a8:0101:: 。 那么 /etc/network/interfaces 文件应该配置成如下: #IPV6 static configuration(我是注释) iface eth0 inet6 static pre-up modprobe ipv6 address 2002:c0a8:10a:: netmask 64 gateway 2002:c0a8:0101:: 注意 “pre-up” 命令。这一行保证系统在启动的时候加载支持ipv6的模块。 最后重新启发动网络,如下: # /etc/init.d/networking restart 你现在可以使用你的IPv6地址了。 测试IPv6地址: 检测路由: # ip -6 route show 如果IPv6工作正常的话,应该会有如下的提示。 2002:c0a8:0100/64 dev eth0 proto kernel scope link src 2002:c0a8:10a ...

July 1, 2012 · 1 min · kamus

X86平台的中断和异常

英特尔的官方文档如下定义x86平台下的中断和异常: 中断: 可屏弊中断(Maskable Interrupts) 所有由I/O设备发出的IRQ(Interupt Requests)都是可屏弊中断。可屏弊中断可以有两个状态:屏弊和未屏弊。屏弊状态的中断会被中断控制硬件忽略。 不可屏弊中断(Nonmaskable Interrupts) 只有一些关键的事件(如硬件失败)会发出不可屏弊中断。不可屏弊中断总是可以被CPU识别到。 异常: 处理器可侦测异常(Processor-detected Exceptions) CPU执行指令时侦测到不正常的状态(anomalous condition)时产生这个异常。这种异常又根据存在内核栈上的EIP寄存器的值被划分为三组。 错误(Faults) 发生错误时,一般情况下可以被纠正。纠正以后,程序继续运行,不会损失连续性。保存下的EIP寄存器的值就是产生这个错误的指令,当异常处理句柄(exception handler)结束后,程序从这条指令继续运行。 陷入(Traps) 当被中止的指令无需重新执行时就产生陷入,这点与错误(Faults)不同。陷入主要被用来实现调试器。 中止(Aborts) 严重出错。控制硬件出现故障,此时不可能把造成异常的指令精确地址存入EIP寄存器。Aborts被用来报告严重的出错,比如硬件出错或者无效的,不一致的系统表结构。由控制硬件单元发出的中断信号被用来把控制权转交给中止异常句柄(Abort Exception Handler)。句柄通常只有强制结束造成Abort的程序。 可编程异常(Programmed Exceptions) 这是由程序员发出的。程序员可以用int 或者int 3指令发出可编程异常。Into(检查溢出)bound(检查数组越界)指令也可以用来发出可编程异常。可编程异常常常被称之为软中断(software interrupts)。这种异常通常用来实现系统调用,还被用来在调试器中报告事件。(into和bound指令在IA64体系中已经被废弃了,见另一篇博文:C语言和它的安全性) copyright ykyi.net

June 30, 2012 · 1 min · kamus

It’s a mistake to include Xen in a Linux distro

As the title show, it’s a mistake to include Xen in a linux distro. Why? Somebody would argue that Xen is a very useful technology. Xen does the virtualization work very well and many projects are using Xen which prove Xen is so great. I’m not mean Xen is not good. However, just because Xen is a hypervisor that is based on another microkernel that is not Linux kernel itself. Linux distros that ship Xen today actually are running an entirely different Operating System kernel that most users even don’t notice that. Xen should be a separate, purpose-built kernel, so it should never be a part of the Linux kernel. Isn’t it strange that you think you are running a linux OS, but this ’linux’ has a kernel that is not linux, which is another kernel. You take away the Linux kernel, how could you say the OS is Linux. ...

June 22, 2012 · 2 min · kamus

traceroute failed.Specify protocal traceroute used manually to fix it.

Today, I ran the traceroute program on a machine running FreeBSD. It failed once and again. Traceroute complained: traceroute: sendto: Permission denied. So I tried to ping. Ping failed, too. I then checked out the configuration of the firewall, which actually denied the pass through of ICMP packet. So I set it to allow ICMP pacakges to pass through the firewall. Ping worked as I expected. But traceroute still failed. ...

June 20, 2012 · 1 min · kamus

如何正确地提交内核补丁包

原文:https://lwn.net/Articles/500443/ 翻译:ykyi.net Greg Kroah-Hartman(又Greg KH)在执行一个了不起的作务:减少内核开发者,尤其是维护者的暴躁情绪。他在日本横滨举行的全球Linux大会上的讲演呼吁公众理解内核维护者的工作,内核贡献者的什么样的行为会导致内核维护者变得暴戾。但是,如果内核贡献者们能够遵守一些约束,他代表他自己做了许多承诺。 Greg Kroah Hartman把Linux内核称之为"有史以来最宏大的软件开发项目",而且它的开发速度也是“亘古未有”。从3.0到3.4,有373个公司的2833位开发者参于了Linux内核的开发。这一年,(2011年的5月到,2012年的5月),Linux内核在每个小时会有5.79处变动。而且这个开发速度仍然要加速,如果你看看3.4的开发过程,每小时共有7.21处变动。这里所说的变动仅仅指能够被合并到主干的补丁包,而那些被拒绝的补丁包没有被统计进来。 补丁包修改了哪些文件,内核开发者就把补丁包发给负责这些文件的维护者。所以的内核维护者,现在大概有700人。他们把改变应用到130个子系统的维护者那里。再从子系统的维护者到Linus的Linux内核代码分支。最后并必Linux内核的主干。如果提交的补丁包一路通过的话。 因此,来看看为什么一些补丁包不会被接受呢?Greg Kroah Hartman以刚过去的两个星期收到的补丁包为例,这两个星期刚好处于3.5版本的Merge Window时间。Merge Window是一个他确不应该接收到许多补丁包的时间段。他应该在Merge Window开始前收到所以有可能会在Merge Window其间被发往Linux Torvalds的补丁包。不过,他说他在这两个星期的时间里收到487个补丁包。其中的大多数都有很多问题,有些补丁包来自那些本应该对内核有更好理解的内核开发者们。 坏的补丁包 Greg KH举例说明了一些他收到的坏的补丁包。其中一个补丁包被命名为:patch 48/48(一个有48个补丁集的最后一个),但是其它的47个都没有。他还收到一堆补丁但没有写清楚先后顺序。如此,他要么猜测一个顺序,这毫无疑问会失败。另一个替代方案就是安全不管这个补丁了。另外还收到过有10个补丁的补丁集,但是2号补丁确丢失了。 ...

June 20, 2012 · 5 min · kamus

Linux内核维护者的职责

原文: http://www.linuxfoundation.org/news-media/blogs/browse/2012/06/role-linux-kernel-maintainer 翻译: ykyi.net 几个星期前在日本举行的Linux大会(LinuxCon)上,我做了一个演讲,题目是"Linux内核维护者,他们在做什么,如何能够帮到他们"。 这个演讲的视频可以通过这个链接看到。如果你想要幻灯片,和我的讲演稿,可以在这个地址获得。 ...

June 20, 2012 · 1 min · kamus

使用Cscope阅读大型工程Linux内核的源代码教程

Cscope是一个非常有用的工具,可以用来方便地阅读很大型工程的源代码。较之使用传统的Unix工具grep,使用Cscope可以省下你一大笔时间,大大提高阅读代码的效率。 通过本教程,我会教给你如何使用Cscope阅读Linux内核的源代码。毫无疑问,你可以举一反三,用同样的方法阅读其它的大型工程的源代码,不仅仅是C语言写的工程,也可以是Java或者C++或者C#开发的工程。 STEP 1 获得源代码: 去到Linux内核的网站http://www.kernel.org下载随便一个版本的Linux内核源代码压缩包。然后解压缩,把源代码释放到某个目录。本文假设你把源代码释放到 /home/code/linux-2.6.26。 STEP 2 选择一个目录存放Cscope所需要的数据库文件。 本文假设选择用/home/cscope目录存放cscope的数据库文件和其它一些相关文件。 STEP 3 生成文件 cscope.files 在最简单的情况下,工程目录下的所有源代码都是我要关心的,于是可以跳过下面所述,简单地在工程的根目录下运行’cscope -R’命令,这样Cscope就会在工程目录下所有源代码中处理相关工作。 但是你关心的代码并必工程目录下所有的代码,你还需要排除很多目录下的大量代码该如何做呢?在这种情况下,你需要生成一个文件cscope.files,这个文件包含 了所有cscope将要扫描的文件的文件名,每个名字占一行。最好使用绝对路径,这样你就可以在其它目录下,而不是现在创建cscope.files文件的目录下使用这个刚创建的数据库。下面的代码将完成这个任务(假设我要所有的java文件): $ cd / $ find /my/project/dir -name “*.java” > /my/cscope/dir/cscope.files 对于Linux内核来讲,情况还要稍微复杂一点。因为我们还要排除好些文件夹,这些文件夹有存放文档的文件夹,存放脚本的文件夹,与处理器架构相关的汇编代码的目录夹,与处理器架构相关的C代码除了x86(大多数人已经仅仅对x86感兴趣),另外还会排除所有的驱动文件目录夹,因为驱动占了内核很大一部分,但驱动代码通常不是我们要关心的。如果不排除这些目录的话,cscope当然也能工作,但是却给我们增加了麻烦,因为大大增加了重复的定义出现的概率。下面看我怎么做: $ LNX=/home/linux-2.6.26 $ cd / $ find $LNX \ -path "$LNX/arch/*" ! -path "$LNX/arch/i386*" -prune -o \ -path "$LNX/include/asm-*" ! -path "$LNX/include/asm-i386*" -prune -o \ -path "$LNX/tmp*" -prune -o \ -path "$LNX/Documentation*" -prune -o \ -path "$LNX/scripts*" -prune -o \ -path "$LNX/drivers*" -prune -o \ -name "*.[chxsS]" -print >/home/jru/cscope/cscope.files ...

June 12, 2012 · 1 min · kamus