一、linux内核学习之一:环境搭建--安装Debian7.3


本系列文章假设读者已对linux有一定的了解,其实学习linux内核不需要有很深的关于linux的知识,只需要了解以下内容:linux基础知识及基本shell命令;现代操作系统的基本概念;C语言和gcc基本使用。


在开始我们的linux内核学习之前。首先需要搭建我们的工作学习环境,即安装linux系统。关于linux系统构建本身的学问已经复杂到可以成为一个独立的学科了,毕竟这不是我们学习的内容,所以我选择最简单的方法:选择一个linux发行版进行安装。


1、选择linux发行版

即使使用最简单的构建工作环境的方法,也耗费了我许多时间。


"选择"之所以这样困难,正是因为可供选择的太多了!


linux发行版有成百上千种,每个发行版都有不同的特点,确实让人难于取舍。我先后试装过Gentoo,Arch,debian,fedora。发行版的选择见仁见智,我不敢说哪个发行版好,哪个不好,每个发行版都有它的拥趸。这里 建议在选择时考虑几个问题:设计哲学,社区支持和包管理器。


实际上,选择哪种发行版都关系不大,发行版之间的差别基本上都是外围组件,对linux的内核的修改都不会很多。


况且我们在学习linux内核,或者开发linux驱动时,一般都是以官方内核(即Linus维护的主线内核)为基准.所以我们搭建好环境后几乎都是要选择一个版本的官方内核来重新编绎以备用的。


现阶段有时间可以多试试不同的发行版,选择自己最喜欢,用起来最顺手的,一旦选择好了,就不要再改了,一直坚持用它,把它用得滚瓜烂熟.人们会关注你在linux环境中是否得心应手,一般不会关心你懂得用多少种linux发行版。


经过反复的试用,比较,我最终选择了Debian,吸引我的是它的崇尚自由的设计哲学;强大的社区支持;数量庞大的软件包. 相对而言debian还是比较保守的,我用的当前的最新稳定版Debian7.3,在2013年12月发布,它使用的内核还是3.2的(现在官方最新的稳定版内核为3.12.8),不过它配套的工具如GCC,make等,即使用来编绎最新版的内核也已经够用了。


2 、选择主机环境

网上很多有经验的linux专家级人物都建议直接在自己的工作机或家庭机上安装linux系统,所有日常工作,生活都在linux系统里完成。


不过对于大多数人来说,这太不现实了了。作为桌面系统,当对于windows而言,linux还是有许多不方便的,即使是最近几年非常火的ubuntu,号称可以替换windows的发行版,在日常使用的软件方面,还是有不小的差距;


再者,我们在工作中常常还是需要开发windows程序,而家里更不合适了,家里人基本上都用惯了windows,总不能强迫他们去用不懂的linux系统吧。因此,windows+vmware作为主机环境对于许多人来说,还是第一选择。


另外还需要一台真实电脑上安装linux系统,因为在vmware里的客户系统无法访问主机中一些硬件,如pci设备等,当开发这些设备的驱动时必须在真实机器上调试。


我使用的主机环境有两个:windows 7+vmware10.0.1环境中安装debian以及x86-64位机器上的windows 7+debian双系统。


3 安装准备

安装准备工作的第一步当然是下载安装镜像了。Debian的下载地址:www.debian.org/CD/http-ftp。


因为在公司限制上网,另外也不喜欢老是在线安装软件,就直接下载了一个用于amd64平台的DVD安装镜像.有3G多,常用的软件都有了,需要时直接从DVD里安装就行了,一劳永逸。


3.1 vmware
首先使用vmware创建vmware虚拟机,创建时候,"Guest operation system"选择"Debian 7 64位"这一项。


内核分配512M即可,硬盘20G足够了。vmware虚拟机可以直接将iso文件作为客户机的光盘使用,因此安装起来非常方便。


只需要在虚拟设置中的DVD光驱的连接选项设置为"使用ISO映象文件",并指定DVD安装ISO镜像的路径即可(后面为了简洁起见,将这一操作称为"ISO镜像加入虚拟机"),接下来开机即可用光盘引导(如果虚拟机磁盘已安装有系统,则需要在虚拟机的BIOS里设置光盘启动,这跟普通电脑设置方法是相同的)。


3.2 x86-64机器

在真实的机器上,使用U盘安装更加方便。我们将在已装windwos7的x86-64机器上用U盘安装,确保你的电脑能用U盘启动,如果不行只能选择烧写ISO到DVD光盘中用光盘安盘了。其次要确保硬盘有足够的空间,如果没有的话,可以调整windows使用的磁盘空间大小(如果不懂设置方法,可以自己百度一下),我的硬盘预留了20G的空间。


接下来制作U盘安装盘,这里需要用到Universal-USB-Installer工具(我用的是1.9.5.1版本)。步骤如下:

在windows系统下插入U盘;打开Universal-USB-Installer程序;

在step1中选择"try unlisted linux ISO";

step2中选择DVD安装ISO的路径;step3选择要安装的U盘(推荐勾选"Format");

开始写入U盘,经过几十分钟的等待,U盘安装完毕,可以使用该U盘启动了。

(用U盘启动的方法与主板的类型相关,可在网上搜索相关的内容)


4 安装系统

为了使用方便,两个系统将采用相同的安装配置,另外我只安装基本的shell环境和必要的工具软件。


使用GUI模式虽然美观,看起来爽,但是对我们这些硬件资源贫乏的穷人来说,运行GUI就是种浪费;其次,与windows不同,linux的X Window完全运行在用户态,与内核关系不大;再者,在漂亮的桌面环境上放一个终端窗口,总觉得很怪异。


我觉得内核和驱动开发者都应该用shell环境,只在需要进行UI相关的测试或编写UI程序时才使用GUI环境。


言归正传,继续进行我们的系统安装吧。经过上面的步骤,不管是vmware还是x86-64机器,debian安装界面总算是出现了。


选择"advanced option"-->"expert install"进入专家安装模式(现在专家那么多,咱也来冒充一回吧!!)。弹出了一列选项,其实里面有很多选项都没必要使用的,大部分都可以在系统安装完成后进行设置。


选项列表的前面是安装语言和键盘设置,这些可以跳过,就用默认的English就行了,反正在文本模式下也显示不了中文。首先要执行的是" Load installer components from cd",这一步会加载ISO(或U盘)中的安装组件,全部选择默认则可。


加载完后,安装选项又多了不少。下一步可以"setup user and passwords",在配置选择中,最好选择“不使用root帐号”,root帐户权限太大,现在的linux界普遍认为不用为妙,可以使用sudo工具执行特权操作,创建自己的用户名和密码,按提示操作即可。


接着就要配置磁盘分区了,首先要"detect disks",让安装程序先检测磁盘,然后进行"partition disks",怕安装程序弄坏我的磁盘,我喜欢选择了"Manual"模式。懒得去设计分区,将剩余空间全部划成了一个"/"分区,分区的属性分别是:"ext4"类型,"primary","bootable"选项。完成分成,忽略关于没有交换分区的警告,写入磁盘就完了。


现在可以开始"install the base system"。安装过程中有个提示,问你要选择哪个内核,我选了"linux-image-3.2.0-4-amd64",没去研究供选择的两个内核有何不同;接下来又提示initrd的选择,为了节省空间,选择了"targeted:only ....."。


接下来可以"configure the package manager",因为我不想让系统连网,所以就在"use a network mirror"选择了"no",另外其他的"service"也全部不选,当然这些选项都可以在系统安装好以后进行修改。


最后选择安装软件:"select and install software",在软件列表中,我只选择了安装"standard system utilities",其他全部不装。


到这里,实质上的系统已经安装完了,就差引导部分了。有grub和lilo可选,我更喜欢grub,因此选择:"install the grub boot loader"。debian7.3用的是grub2,功能非常强大。


在安装过程中grub会自动检测当前磁盘中安装的其他的系统,可以放心将grub安装到MBR中,不必担心你的windows会无法启动。安装完毕,选择"finish the install",重启系统吧!


5 安装开发工具

现在我们有了一个基本的debian系统,但是还没有gcc等开发工具,无法进行日常工作,需要安装这些工具。


5.1 设置安装源

debian的包管理器非常完善,我们现在安装软件就用debian强大的apt-get命令。但是在使用前要先配置安装源,以告诉apt-get命令去哪里找我们的软件。


安装软件尽量都从下载的ISO安装,既然下载了那么大的一个ISO镜像,就别浪费了。debian可以设置几种安装源,如CD安装源,网络安装源,本地安装源。


5.1.1 设置CD安装源

在vmware中,可以将ISO文件当作光盘使用,实在是太方便了。因此,在vmware中我们设置以CD作为安装源,实际上在安装系统时,系统的包管理器就已经把DVD安装盘加入安装源了,可以查看/etc/apt/sources.list文件。


如果没有加入,或者想加入别的CD安装源也非常简单,只需执行以下操作:

  • 将ISO加入虚拟机

  • 挂载光盘:sudo mount /dev/cdrom /media/cdrom

  • 将光盘加入安装源:sudo apt-cdrom add

  • 打开/etc/apt/sources.list查看是否添加成功

  • 更新软件件表:sudo apt-get update


5.1.2 设置本地安装源

在真实的x86-64机器上,系统无法把安装U盘识别为光盘,不能将安装U盘作为CD安装源加入。


不过我们可以将ISO文件挂载到某个目录,再将该目录作为本地安装源加入包管理器,步骤如下:

  • 创建本地安装源目录:sudo mkdir /mnt/iso_1

  • 挂载ISO文件到该目录:sudo mount /.../debian-*.iso /mnt/iso_1

  • 添加本地安装源:打开/etc/apt/sources.list,添加一行,内容为:deb file:///mnt/iso_1 wheezy main

  • 更新软件列表:sudo apt-get update


5.2 安装开发工具

5.2.1 安装VIM,执行命令:sudo apt-get install vim

安装系统时安装的是精简版的VIM:vim.tiny,功能不齐全,因此安装完整的VIM,喜欢其他代码编辑工具的网络可以安装其他工具。


VIM安装完后进行配置,在/etc/vim/vimrc文件最后加上以下几行(不包括括号内容):

  • set nobackup        (打开时不创建备份文件)

  • set ts=4                 (设置tab键宽度为4个字符宽)

  • set atuoindent       (启用自动缩进功能)

  • set cindent       (启用C语言缩进功能)

  • set shiftwidth=4     (缩进宽度为4个字符宽)

  • syntax on              (打开语法高亮功能)


5.2.2 安装开发工具包:sudo apt-get install build-essential

build-essential包含了常用的gcc,g++,make等开发工具.


5.2.3 安装linux-headers:sudo apt-get install linux-headers-3.2.0-4-amd6

需要编绎系统自带内核相关的模块时,必须安装该内核对应的linux-headers,里面包含内核配置信息,内核头文件等。


5.2.4 安装ncurses-dev:sudo apt-get install libncurses5-dev

内核配置脚本依赖于该工具,如果没有安装的话,配置内核里会出错。


5.2.5 安装git:sudo apt-get install git

著名的流行的分布式版本管理工具,由Linus开发,官方内核开发用的版本管理工具也是git。Linus的作品,不能不用啊!


git需要先配置用户名和email:

  • git config --global user.name "xxxxxx"

  • git config --global user.email "xxxxxx@xxx.com"


6 环境搭建完成

可以正式开始我们的linux内核学习之旅了。


二、linux内核学习之二:编译内核


环境搭好后,马上就进入到下一环节--编译内核。linux的内核是整个系统最核心的部分,内核的功能基本上决定了系统的能力。


linux的内核代码使用的是GPL授权,允许自由下载,修改并重新发布内核,只要求发布修改后的内核的同时提供源代码。


各种各样的内核版本众多,几乎所有的linux发行版都会对内核进行或多或少的修改,debian也不例外。这些内核都有个源头,即Linus维护的官方内核,其他的内核几乎都是建立在官方内核的基础上的。我们的内核学习,也是以官方内核为准。


linux官方内核的网站是:www.kernel.org。从里面可以了解到内核开发的最新动态,现在就把该网址加入收藏夹吧。

(另外有个网站:www.lwn.net里面有许多linux大牛发表的观点,也值得收藏)。


从linux内核3.0开始,内核版本命名采用的策略跟以前不一样,命名格式为3.A.B,其中A为内核的版本,B为补丁的版本。即3.A.B与3.A.C的内核是相同的版本,具有相同的功能,如果C>B,只是说明3.A.C相比3.A.B修补了一些BUG而已。


进入内核3.0时代后,内核的开发工作发展迅速,版本更新得很快,第一个3.0版本是在2011年7月,而现在,最新的稳定版已是3.12.8,而新的3.13版内核开发工作也已接近尾声,即将发布稳定版了。("zh.wikipedia.org/wiki/linux"内核"介绍了部分版本的特性)。 


1 选择内核版本

首先我们需要从www.kernel.org选择一个版本。实际上从2.6版本开始,内核的架构没有特别大的变动,基本上是添加新的功能,添加新的驱动的支持,内核接口有一些变动。


另外,除非不得已,不要再使用2.4及更低版本,因为2.6内核的整个架构经过全面重新设计,效率更高,功能更完善,也更安全。


我觉得尽量选择与发行版使用的内核版本差不多的话会比较好点,内核跟其他组件相对会配合得好些,不知是不是这样。debian7.3使用的内核是3.2的,而现在该内核版本的最新版为3.2.54,使用相同内核版本的带有最新补丁的内核重编译并替换原来的内核,可以最大程度上减少与系统其他部分的兼容性问题,这样我们可以将主要精力集中在内核的学习上。


下载得到的内核名为linux-3.2.54.tar.xz。


下面将描述在上一课中搭建的“windows7+vmware10.0.1+debian7.3”的系统中编译内核linux-3.2.54的步骤,在真实机器上安装的debian7.3系统上编译的方法也是类似的。


2 安装vmware-tools

内核文件下载好后,需复制到vmware客户系统(即debian系统)。


最好的方法是使用vmware提供的文件共享功能,这个功能由vmware-tools软件包提供,需要先安装该软件包。首先设置共享目录,在VMware菜单栏上点击"虚拟机"-->"设置",打开设置页面,点击"选项"属性页,点击"共享文件夹",在右端选择"总是启用",再点击"添加",按提示设置主机中用于共享的目录路径和共享名称(我用的是workspace)。


启动debian系统后,点击菜单栏的"虚拟机"-->"安装VMWare Tools"。稍等片刻后,虚拟机的CD光驱动应该已经有了vmware-tools的安装盘。在debian系统按以下步骤进行:
挂载光盘:sudo mount /dev/cdrom /media/cdrom
复制安装包: cp /media/cdrom/VM*.tar.gz ./
解压安装包:tar -xvf ./VM*.tar.gz
cd ./vmware-tools-distrib
安装:sudo ./vmware-install.pl(安装过程中所有选项都使用默认即可)


安装完成了,检查发现/mnt目录下多了一项hgfs目录,里面是主机共享目录,即/mnt/hgfs/workspace。


3 准备新的内核源代码

将下载的内核源代码放在上一步中设置的主机共享目录中,然后解压到默认的内核源代码目录:sudo tar -xvf /mnt/hgfs/workspace/linux-*.tar.gz -C /usr/src

/usr/src目录下是专门存放内核源代码的。


放在其他目录也可以编译的,不过我们还是遵循通用的规则吧。


我们的debian系统是64位版本(正式名称是x86_64),为了避免出现问题,我们的内核也将编译成x86_64版本,故修改下源代码目录名称:sudo mv /usr/src/linux-3.2.54 /usr/src/linux-3.2.54.x86_64.同时把源代码目录下的Makefile文件内容也改一下:
sudo vim /usr/src/linux-3.2.54.x86_64/Makefile
搜索字符串"EXTRAVERSION =",在"="后面加上".x86_64"。


这样,编译出来的内核镜像,模块目录等都会自动加上".x86_64"后缀。


4 配置内核

配置内核就是告诉编译器,源代码中的哪些功能要编译进内核,哪些编译成模块,哪些不需要编译。源码中包含了几千个选择,因此配置内核是个很复杂很吃力的工作,为了简化这个工作,内核开发者为各个平台编写了默认的简单配置文件。以x86平台为例,配置文件放在"arch/x86/configs"目录下,可将这些配置文件作为配置工作的起点,选择其中一个文件复制到源码目录下,并命令名为".config"(注意前面有个".",它是隐藏文件),这是内核编译时使用的配置文件,也是内核配置工具启动时加载的文件,当然内核配置修改后的配置信息也保存在这个文件里。


由于VMWare的硬件与普通的硬件不同,用内核开发者提供的配置文件编译出来的内核无法引导系统,我们先暂时忽略有关内核配置的复杂细节,走条捷径,以debian系统安装时产生的配置文件作为我们配置内核的起点。


既然debian能引导,用它编译出来的内核应该不会有什么大问题,复制debian的配置文件到源代码目录,并配置:
sudo cp /boot/config-3.2.0-4-amd64 /usr/src/linux-3.2.54.x86_64/.config
cd /usr/src/linux-3.2.54.x86_64/
sudo make menuconfig

即使不修改内核的配置还是需要执行sudo make menuconfig,因为发行版的内核可能经过修改,使用的.config也可能会有差异,执行一下sudo make menuconfig,它会重新分析.config文件,设置文件中描述的配置信息,退出后再保存成新内核适用的.config文件(退出时,配置工具会询问你是否保存修改,需要选择"yes")。


5 编译,安装新内核

内核配置完成了,可以编译内核了,分别执行以下命令,进行编译并安装内核:

sudo makesudo make modules_installsudo make install

make命令根据配置信息进行编译,包括模块。debian系统默认加入了许多驱动模块,整个编译过程比较耗时,估计长达1.5~2个小时,在编译时可能出现各种问题,需要根据错误提示进行修改。


本次编译模块时就提示“drivers/staging/rts5139”这个模块编译出错,这是一个USB读卡器的驱动,不是什么必需的驱动,直接在内核配置中去掉该模块吧。


因此,重新执行sudo make menuconfig,找到该模块:“Device Drivers”-->"Staging drivers"-->"Realtek RTS5139 USB card reader support"。去掉该模块支持,退出保存,重新执行sudo make。


make modules_install命令用于安装可装载模块,这些模块会自动安装到/lib/modules/3.2.54.x86_64下。  

   

make install命令执行三个操作:复制内核镜像到/boot目录下;生成initrd-img;更新grub。命令成功执行成功后,新的内核已可以使用,并且列在引导菜单中。


6 重启系统

重启系统,grub引导选项中多了我们新编译的内核选择,选择新内核引导。进入系统后执行命令uname -r 查看当前的内核版本,显示为“3.2.54.x86_64”,确实是我们新编译的内核。


不过,在VMWare中重编译内核后,vmware-tools的文件共享功能不起作用了,这是因为vmware-tools中包含了内核模块,重编译后,这些模块不能再正常加载了。


只需执行命令:sudo vmware-config-tools.pl(全部使用默认选项),重新配置vmware-tools即可让共享功能正常使用。