Linux内核中的宏可变参数(GCC的宏可变参数)

Linux内核中的宏可变参数(GCC的宏可变参数)。 写内核模块的时候为了调试方便,经常需要wrap一下printk函数。下面的宏定义非常有实用价值。 注意两个井号~~ 记到博客里~~ #define seclvl_printk(verb, type, fmt, arg...) \ do { \ if (verbosity >= verb) { \ static unsigned long _prior; \ unsigned long _now = jiffies; \ if ((_now - _prior) > HZ) { \ printk(type "%s: %s: " fmt, \ MY_NAME, __FUNCTION__ , \ ## arg); \ _prior = _now; \ } \ } \ } while (0)

February 17, 2013 · 1 min · kamus

使用gdb和虚拟机调试内核

调试内核很麻烦,即使是有了虚拟机的帮助。在这里记下一些关键的东西,以备忘 。 # 编译内核后, 用新内核启动系统失败,报错 “unable to mount fs ….” 之类. 需要用 update-initramfs 生成initram。 # 对于grub2,我增加了一个自定义的grub开机启动项用来调试内核,如下: #!/bin/sh exec tail -n +3 $0 # This file provides an easy way to add custom menu entries. Simply type the # menu entries you want to add after this comment. Be careful not to change # the ’exec tail’ line above. echo “Add Debugging entry” cat « EOF menuentry “Debian debug 3.7.4”{ set root=(hd0,1) linux /boot/vmlinuz-3.7.4 root=/dev/vda1 ro quiet kgdboc=ttyS0,115200 kgdbwait initrd /boot/initrd.img-3.7.4 } EOF ...

January 28, 2013 · 1 min · kamus

Linux内核Makefiles教程(二)

接第一篇 **3.3.**可加载模块目标 obj-m (Loadable module goals – obj-m) obj-m指定将被构建为可加载内核模块的对象文件(object file)。 一个模块可以从一个源文件构建或者从多个源文件构建。如果模块仅仅从一个源文件构建,kbuild makefile仅仅把对象文件加到obj-m。如下: #drivers/isdn/i4l/Makefile obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o _在这个例子中,__$(CONFIG_ISDN_PPP_BSDCOMP)_被求值为__m. If a kernel module is built from several source files, you specify that you want to build a module in the same way as above. 如果一个内核模块需要从多个源文件构建,你也是按照刚才提到的那一行指定。不过,除此之外,还要额外地指定,你的内核模块需要哪些对象文件。所以还需要设置<模块名>-objs变量。如下: #drivers/isdn/i4l/Makefile obj-$(CONFIG_ISDN) += isdn.o isdn-objs := isdn_net_lib.o isdn_v110.o isdn_common.o 在这个例子中,模块名是 isdn 。Kbuild将编译isdn-objs列出的所有对象文件,然后运行$(LD) –r把这些对象文件链接成一个文件isdn.o。 Kbuild用-objs后缀或者-y后缀识别构成复合对象文件(composite objects)的对象文件。这样,Makefile就可以使用CONFIG_* 符号来确定一个对象文件是不是一个复合对象文件的一部分。如下: #fs/ext2/Makefile obj-$(CONFIG_EXT2_FS) += ext2.o ext2-y := balloc.o bitmap.o ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o ...

July 7, 2012 · 1 min · kamus

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

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

原文: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

KVM你问我答 FAQ (四)

KVM和Xen有什么区别? Xen是一个外部虚拟机管理程序(External hypervisor),它承担了管理物理机器的任务并把物理机器的各种资源分配给客户机。与Xen不同,KVM本身是Linux内核的一部分,它使用Linux自己的进程调度和内存管理。这就天然决定了KVM易于使用并于体积会很小。仅管体积小,但KVM的功能确不少。比如,KVM可以把客户机从内存中兑换到物理磁盘上,如同swap普通进程一样释放RAM。KVM目前只在提供支持硬件虚拟化的x86机器上运行(如vt/svm指令集)。从这这方面讲,Xen通过修改客户机操作系统,充许虚拟机运行在没有硬件虚拟化技术的x86平台上运行。这种虚拟化技术称之为准虚拟化paravirtualization,参见另一贴:Linux的虚拟化技术。KVM在CPU级别不支持paravirtualization,但为了指高I/O性能,会对设备驱动程序支持准虚拟化。 KVM和Vmware有什么区别呢? VMware是一个商用专用虚拟化产品,KVM是在GPL许可证下发布的自由软件。 KVM和QEMU有什么区别? QEMU是模拟器。参见Linux的虚拟化技术 KVM & QEMU 。 KVM有windows下的移移植版本吗? ...

June 11, 2012 · 1 min · kamus

KVM你问我答 FAQ (三)

我在使用QEMU,如何知道我有没有启用KVM的硬件加速功能? 如果你怀疑你没有启用KVM提供的硬件加速功能。你可以按照下面的步骤做检查。首先,看看你有没有得到下面的提示信息: qemu-system-x86_64 -hda myvm.qcow2 open /dev/kvm: No such file or directory Could not initialize KVM, will disable KVM support 如果是这种情况,请再检查: kvm模块被正确载入了吗? lsmod | grep kvm. 查看 dmesg 的输出,保证没有这个提示信息: “KVM, disabled by BIOS”. 请确保/dev/kvm 确实存在,而且你有权限使用它。 其它诊断方式: 如果你能使用 QEMU monitor ( ctrl-alt-2, 再 ctrl-alt-1 回到 VM 的显示屏 ),敲入 info kvm 命令。如果正常的话,应该有“KVM support: enabled”这条信息输出。 在host机上敲 lsmod | grep kvm 命令,看看输出的最右栏。如果kvm在正常运行的话,这个数字不能是0。这行的数字与架构相关的模块(一般指的是kvm_intel,或kvm_amd)有联系,它显示了有多少个VM正在使用这个模块。举例说明,如果你有两个虚拟机正在使用KVM模块,host机的CPU使用的是vt技术,那么就会得到: # lsmod | grep kvm kvm_intel 44896 2 kvm 159656 1 kvm_intel ...

June 10, 2012 · 2 min · kamus

KVM你问我答FAQ (一)

使用KVM需要哪些准备? ****你需要一台运行Linux的x86的机器。它的CPU是有VT技术支持的英特尔cpu或者有SVM(又常被称为AMD-V)支持的AMD的CPU. KVM支持64位的处理器吗? ****KVM支持64位的处理器!此时,你可以运行32位或者64位的客户机。 What is Intel VT / AMD-V / hvm? 英特尔VT,是什么?AMD-V又是什么?hvm是什么? Intel VT 和AMD’s AMD-V 都指的是指令集扩展。它们在硬件层面帮助实现虚拟机管理技术。这种技术使得在虚拟机上运行的速度接近直接在真实机器上运行的速度。HVM是硬件虚拟机的缩写(Hardware Virtual Machine )则是一个生产商中立的词汇(vendor-neutral term),它常常用来指代x86指定集扩展。 从哪里得到KVM内核模块呢? ****可以从这里获得 http://www.linux-kvm.org/page/Getting_the_kvm_kernel_modules 。 我如何知道我的CPU支持Intel VT技术或者AMD-V技术呢? 如果你的Linux操作系统比较新,尝试以下的指令: . egrep ‘^flags.(vmx|svm)’ /proc/cpuinfo* 如果出现一些文字,那说说你的CPU支持虚拟化。你也可以在/proc/cpuinfo文件中找到处理器模块的名字,然后到供应商的网站上查询。 注意: 如果安装了Xen hypervisor,为了防止被劫持,你在dom0和domU中都得不到这些输出。dom0和domU是Xen hypervisor的术语。如果你没有安装Xen,直接忽略。 一些产商默认在BIOS定设中禁用了CPU的虚拟化支持。你需要先在BIOS中打开虚拟化支持。 如果你用的是intel cpu,对于内核版本2.6.15以前的Linux,你得不到这样的输出。如果你用的是amd cpu,对于内核版 本2.6.16以前的linux,你得不到这样的输出。如果你不确定你的Linux内核版本,用#uname -r 命令查看。 出现 “KVM: disabled by BIOS” error 错误 Check if there is an option to enable it in the BIOS. If not, look for a more recent BIOS on the vendor’s web site. 在BIOS设定在找找看有没有启用cpu虚拟化的选项,如果没有,去到主板厂商的网站上面看看有没有新的BIOS发布并支持打开cpu虚拟化,那么你需要刷新BIOS. 注意: 1.对于部分硬件(如 HP nx 6320),你需要先关掉主机电源,再打开主机电源才能使BIOS中启用cpu虚拟化支持生效。 2.BIOS的部分设定有可能与启用CPU虚拟化冲突。比如在Thinkpad T500上,启用Intel AMT技术会出现冲突。这样kvm-intel在载入时会抱怨”disabled by bios”错误。 3. 在一些Dell的硬件中,你还需要禁用”Trusted Execution”,否则不能打开VT。 ...

June 9, 2012 · 1 min · kamus