当前位置:首页 » 操作系统 » linux内核源码011

linux内核源码011

发布时间: 2022-12-31 08:33:25

‘壹’ 如何查看 linux 内核源代码

Linux的内核源代码可以从很多途径得到。一般来讲,在安装的linux系统下,/usr/src/linux目录下的东西就是内核源代码。

对于源代码的阅读,要想比较顺利,事先最好对源代码的知识背景有一定的了解。对于linux内核源代码来讲,我认为,基本要求是:1、操作系统的基本知识;2、对C语言比较熟悉,最好要有汇编语言的知识和GNU C对标准C的扩展的知识的了解。另外在阅读之前,还应该知道Linux内核源代码的整体分布情况。我们知道现代的操作系统一般由进程管理、内存管理、文件系统、驱动程序、网络等组成。看一下Linux内核源代码就可看出,各个目录大致对应了这些方面。Linux内核源代码的组成如下(假设相对于linux目录):

arch 这个子目录包含了此核心源代码所支持的硬件体系结构相关的核心代码。如对于X86平台就是i386。

include 这个目录包括了核心的大多数include文件。另外对于每种支持的体系结构分别有一个子目录。

init 此目录包含核心启动代码。

mm 此目录包含了所有的内存管理代码。与具体硬件体系结构相关的内存管理代码位于arch/*/mm目录下,如对应于X86的就是arch/i386/mm/fault.c 。

drivers 系统中所有的设备驱动都位于此目录中。它又进一步划分成几类设备驱动,每一种也有对应的子目录,如声卡的驱动对应于drivers/sound。

ipc 此目录包含了核心的进程间通讯代码。

moles 此目录包含已建好可动态加载的模块。

fs Linux支持的文件系统代码。不同的文件系统有不同的子目录对应,如ext2文件系统对应的就是ext2子目录。

kernel 主要核心代码。同时与处理器结构相关代码都放在arch/*/kernel目录下。

net 核心的网络部分代码。里面的每个子目录对应于网络的一个方面。

lib 此目录包含了核心的库代码。与处理器结构相关库代码被放在arch/*/lib/目录下。

scripts此目录包含用于配置核心的脚本文件。

Documentation 此目录是一些文档,起参考作用。

俗话说:“工欲善其事,必先利其器”。 阅读象Linux核心代码这样的复杂程序令人望而生畏。它象一个越滚越大的雪球,阅读核心某个部分经常要用到好几个其他的相关文件,不久你将会忘记你原来在干什么。所以没有一个好的工具是不行的。由于大部分爱好者对于Window平台比较熟悉,并且还是常用Window系列平台,所以在此我介绍一个Window下的一个工具软件:Source Insight。这是一个有30天免费期的软件,可以从www.sourcedyn.com下载。安装非常简单,和别的安装一样,双击安装文件名,然后按提示进行就可以了。安装完成后,就可启动该程序。这个软件使用起来非常简单,是一个阅读源代码的好工具。它的使用简单介绍如下:先选择Project菜单下的new,新建一个工程,输入工程名,接着要求你把欲读的源代码加入(可以整个目录加)后,该软件就分析你所加的源代码。分析完后,就可以进行阅读了。对于打开的阅读文件,如果想看某一变量的定义,先把光标定位于该变量,然后点击工具条上的相应选项,该变量的定义就显示出来。对于函数的定义与实现也可以同样操作。别的功能在这里就不说了,有兴趣的朋友可以装一个Source Insight,那样你阅读源代码的效率会有很大提高的。怎么样,试试吧!

‘贰’ linux编译内核步骤

一、准备工作
a) 首先,你要有一台PC(这不废话么^_^),装好了Linux。
b) 安装好GCC(这个指的是host gcc,用于编译生成运行于pc机程序的)、make、ncurses等工具。
c) 下载一份纯净的Linux内核源码包,并解压好。

注意,如果你是为当前PC机编译内核,最好使用相应的Linux发行版的源码包。

不过这应该也不是必须的,因为我在我的Fedora 13上(其自带的内核版本是2.6.33.3),就下载了一个标准的内核linux-2.6.32.65.tar.xz,并且顺利的编译安装成功了,上电重启都OK的。不过,我使用的.config配置文件,是Fedora 13自带内核的配置文件,即/lib/moles/`uname -r`/build/.config

d) 如果你是移植Linux到嵌入式系统,则还要再下载安装交叉编译工具链。

例如,你的目标单板CPU可能是arm或mips等cpu,则安装相应的交叉编译工具链。安装后,需要将工具链路径添加到PATH环境变量中。例如,你安装的是arm工具链,那么你在shell中执行类似如下的命令,假如有类似的输出,就说明安装好了。
[root@localhost linux-2.6.33.i686]# arm-linux-gcc --version
arm-linux-gcc (Buildroot 2010.11) 4.3.5
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for ing conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
注:arm的工具链,可以从这里下载:回复“ARM”即可查看。

二、设置编译目标

在配置或编译内核之前,首先要确定目标CPU架构,以及编译时采用什么工具链。这是最最基础的信息,首先要确定的。
如果你是为当前使用的PC机编译内核,则无须设置。
否则的话,就要明确设置。
这里以arm为例,来说明。
有两种设置方法():

a) 修改Makefile
打开内核源码根目录下的Makefile,修改如下两个Makefile变量并保存。
ARCH := arm
CROSS_COMPILE := arm-linux-

注意,这里cross_compile的设置,是假定所用的交叉工具链的gcc程序名称为arm-linux-gcc。如果实际使用的gcc名称是some-thing-else-gcc,则这里照葫芦画瓢填some-thing-else-即可。总之,要省去名称中最后的gcc那3个字母。

b) 每次执行make命令时,都通过命令行参数传入这些信息。
这其实是通过make工具的命令行参数指定变量的值。
例如
配置内核时时,使用
make ARCH=arm CROSS_COMPILE=arm-linux- menuconfig
编译内核时使用
make ARCH=arm CROSS_COMPILE=arm-linux-

注意,实际上,对于编译PC机内核的情况,虽然用户没有明确设置,但并不是这两项没有配置。因为如果用户没有设置这两项,内核源码顶层Makefile(位于源码根目录下)会通过如下方式生成这两个变量的值。
SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
-e s/arm.*/arm/ -e s/sa110/arm/ \
-e s/s390x/s390/ -e s/parisc64/parisc/ \
-e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
-e s/sh[234].*/sh/ )
ARCH?= $(SUBARCH)
CROSS_COMPILE ?=

经过上面的代码,ARCH变成了PC编译机的arch,即SUBARCH。因此,如果PC机上uname -m输出的是ix86,则ARCH的值就成了i386。

而CROSS_COMPILE的值,如果没配置,则为空字符串。这样一来所使用的工具链程序的名称,就不再有类似arm-linux-这样的前缀,就相当于使用了PC机上的gcc。

最后再多说两句,ARCH的值还需要再进一步做泛化。因为内核源码的arch目录下,不存在i386这个目录,也没有sparc64这样的目录。

因此顶层makefile中又构造了一个SRCARCH变量,通过如下代码,生成他的值。这样一来,SRCARCH变量,才最终匹配到内核源码arch目录中的某一个架构名。

SRCARCH := $(ARCH)

ifeq ($(ARCH),i386)
SRCARCH := x86
endif

ifeq ($(ARCH),x86_64)
SRCARCH := x86
endif

ifeq ($(ARCH),sparc64)
SRCARCH := sparc
endif

ifeq ($(ARCH),sh64)
SRCARCH := sh
endif

三、配置内核

内核的功能那么多,我们需要哪些部分,每个部分编译成什么形式(编进内核还是编成模块),每个部分的工作参数如何,这些都是可以配置的。因此,在开始编译之前,我们需要构建出一份配置清单,放到内核源码根目录下,命名为.config文件,然后根据此.config文件,编译出我们需要的内核。

但是,内核的配置项太多了,一个一个配,太麻烦了。而且,不同的CPU架构,所能配置的配置项集合,是不一样的。例如,某种CPU的某个功能特性要不要支持的配置项,就是与CPU架构有关的配置项。所以,内核提供了一种简单的配置方法。

以arm为例,具体做法如下。

a) 根据我们的目标CPU架构,从内核源码arch/arm/configs目录下,找一个与目标系统最接近的配置文件(例如s3c2410_defconfig),拷贝到内核源码根目录下,命名为.config。

注意,如果你是为当前PC机编译内核,最好拷贝如下文件到内核源码根目录下,做为初始配置文件。这个文件,是PC机当前运行的内核编译时使用的配置文件。
/lib/moles/`uname -r`/build/.config
这里顺便多说两句,PC机内核的配置文件,选择的功能真是多。不编不知道,一编才知道。Linux发行方这样做的目的,可能是想让所发行的Linux能够满足用户的各种需求吧。

b) 执行make menuconfig对此配置做一些需要的修改,退出时选择保存,就将新的配置更新到.config文件中了。

‘叁’ Linux Kernel (Linux内核)怎么安装

1、下载新内核源码:到官网www.kernel.org,下载最新版本linux内核,保存到/usr/src/kernels目录,大约54MB。
2、# cd /usr/src/kernels
3、# tar jvxf linux-2.6.31.5.tar.bz2
4、进入系统原内核目录,把其中的隐藏文件.config复制到新内核目录中。
5、cd进入新内核目录,然后执行# make oldconfig
此时所有提示均按回车,选项提示都默认。
6、# make xconfig 此时弹出一个内核配置窗口,里面全是英文,我看不懂,干脆就直接把这个窗口关掉,继续往下做。
7、# make bzImage && make moles && make moles_install && make install 第七步编译时间比较长,要30到50分钟不等,要看机器情况了。
8、#uname -r查看内核版本,完成上面步骤后就可以重启系统了,启动时会在GRUB菜单里出现新内核选项了。
此方法安装新内核后同时也会保留旧内核,启动时,可以在新老内核间选择,相当的实用

‘肆’ linux内核~~

用gcc编译一下,就成了内核镜像了
开机时要把镜像加载进内存
在加上些软件,就是一个比较完整的linux了

内核源码书:
linux内核完全注释(0.11/0.12内核)
linux内核源代码情景分析(2.4内核)

要弄明白内核结构,多研究研究Makefile文件

‘伍’ ubuntu下怎么编译linux内核

Ubuntu 系统
1. 准备工作
切换为管理员权限,sudo –i 输入用户密码 进入root 权限
apt-get install build-essential kernel-package libncurses5-dev libqt3-headers
build-essential (基本的编程库(gcc, make 等)
kernel-package (Debian 系统里生成 kernel-image 的一些配置文件和工具)
libncurses5-dev (meke menuconfig 要调用的)
libqt3-headers (make xconfig 要调用的)
2. 下载特定版本的内核源代码
3. 复制源码linux-3.2.12.tar.bz2 到/usr/src 目录,解压缩
命令.假设源码存放在/home 目录下
cp /home/linux-3.2.12.tar.bz2 /usr/src
cd /usr/src
tar xvjf linux-3.2.12.tar.bz2
解压后生成 linux-3.2.12 目录
4. cd linux-3.2.12
接下来配置内核选项
make menuconfig 这一步比较复杂,内核选项很多,可以使用当前内核的配置选项,
但编译内核的时间会比较长,因为装系统的时候使用的配置是适应大多数系统的,非定
制选项。关于内核配置选项怎么定制,网上很多。
5. 把正在使用系统中的内核配置文件/usr/src/linux-headers-2.6.38-13-generic/.config 拷到
/usr/src/linux-3.2.12 目录下
cp /usr/src/ linux-headers-2.6.38-13-generic/.config /usr/src/ linux-3.2.12
执行:
cd /usr/src/ linux-3.2.12
make menuconfig
终端会弹出一个配置界面
注意主菜单最后有两项:
load a kernel configuration…
save a kernel configuration…
先选第一项load ….,意思是,利用当前的内核配置详单来设置将要编译的内核,然后选save 这一项保存,最后退出配置界面
6. 开如编译安装新内核
执行:make mrproper (清除以前曾经编译过的旧文件,如果是第一次编译,可不执行)
执行:make (编译,加-j4,必须加,双核并行编译,速度快很多,不过使用原先配置
选项)
然后:make install
再:make moles (编译模块)
再:make moles_install (安装模块)
最后创建initrd 文件:
mkinitramfs -o /boot/initrd.img-linux-3.2.12
7. make install 以后,系统自动更新了启动项,可以cat /boot/grub/grub.cfg 看下.之前的启动项不能删除,如果编译内核不成功,之前的启动项又不见了,系统也就跪了
8. reboot

‘陆’ linux1.0内核中的头文件在哪

http://www.kernel.org/pub/linux/kernel/v1.0/

如果这里的也没有,那么就说明根本就没有这几个文件。我只找到了网址,没有下载打开来看。

‘柒’ 如何linux内核报告问题

Linux Kernel BUG:soft lockup CPU#1 stuck分析
1.线上内核bug日志
kernel: Deltaway too big! 18428729675200069867 ts=18446743954022816244 write stamp =18014278822746377
kernel:------------[ cut here ]------------
kernel:WARNING: at kernel/trace/ring_buffer.c:1988 rb_reserve_next_event+0x2ce/0x370()(Not tainted)
kernel:Hardware name: ProLiant DL360 G7
kernel:Moles linked in: fuse ipv6 power_meter bnx2 sg microcode serio_raw iTCO_wdtiTCO_vendor_support hpilo hpwdt i7core_edac edac_core shpchp ext4 mbcache jbd2sd_mod crc_t10dif hpsa radeon ttm drm_kms_helper drm i2c_algo_bit i2c_coredm_mirror dm_region_hash dm_log dm_mod [last unloaded: scsi_wait_scan]
kernel: Pid:5483, comm: master Not tainted 2.6.32-220.el6.x86_64 #1
kernel: CallTrace:
kernel:[<ffffffff81069b77>] ? warn_slowpath_common+0x87/0xc0
kernel:[<ffffffff81069bca>] ? warn_slowpath_null+0x1a/0x20
kernel:[<ffffffff810ea8ae>] ? rb_reserve_next_event+0x2ce/0x370
kernel:[<ffffffff810eab02>] ? ring_buffer_lock_reserve+0xa2/0x160
kernel:[<ffffffff810ec97c>] ? trace_buffer_lock_reserve+0x2c/0x70
kernel:[<ffffffff810ecb16>] ? trace_current_buffer_lock_reserve+0x16/0x20
kernel:[<ffffffff8107ae1e>] ? ftrace_raw_event_hrtimer_cancel+0x4e/0xb0
kernel:[<ffffffff81095e7a>] ? hrtimer_try_to_cancel+0xba/0xd0
kernel:[<ffffffff8106f634>] ? do_setitimer+0xd4/0x220
kernel:[<ffffffff8106f88a>] ? alarm_setitimer+0x3a/0x60
kernel:[<ffffffff8107c27e>] ? sys_alarm+0xe/0x20
kernel:[<ffffffff8100b308>] ? tracesys+0xd9/0xde
kernel: ---[end trace 4d0a1ef2e62cb1a2 ]---
abrt-mp-oops: Reported 1 kernel oopses to Abrt
kernel: BUG: softlockup - CPU#11 stuck for 4278190091s! [qmgr:5492]
kernel:Moles linked in: fuse ipv6 power_meter bnx2 sg microcode serio_raw iTCO_wdtiTCO_vendor_support hpilo hpwdt i7core_edac edac_core shpchp ext4 mbcache jbd2sd_mod crc_t10dif hpsa radeon ttm drm_kms_helper drm i2c_algo_bit i2c_coredm_mirror dm_region_hash dm_log dm_mod [last unloaded: scsi_wait_scan]
kernel: CPU 11
kernel:Moles linked in: fuse ipv6 power_meter bnx2 sg microcode serio_raw iTCO_wdtiTCO_vendor_support hpilo hpwdt i7core_edac edac_core shpchp ext4 mbcache jbd2sd_mod crc_t10dif hpsa radeon ttm drm_kms_helper drm i2c_algo_bit i2c_coredm_mirror dm_region_hash dm_log dm_mod [last unloaded: scsi_wait_scan]
kernel:
kernel: Pid:5492, comm: qmgr Tainted: G W ---------------- 2.6.32-220.el6.x86_64 #1 HPProLiant DL360 G7
kernel: RIP:0010:[<ffffffff8106f730>] [<ffffffff8106f730>]do_setitimer+0x1d0/0x220
kernel: RSP:0018:ffff88080a661ef8 EFLAGS: 00000286
kernel: RAX:ffff88080b175a08 RBX: ffff88080a661f18 RCX: 0000000000000000
kernel: RDX:0000000000000000 RSI: 0000000000000082 RDI: ffff88080c8c4c40
kernel: RBP:ffffffff8100bc0e R08: 0000000000000000 R09: 0099d7270e01c3f1
kernel: R10:0000000000000000 R11: 0000000000000246 R12: ffffffff810ef9a3
kernel: R13:ffff88080a661e88 R14: 0000000000000000 R15: ffff88080a65a544
kernel: FS:00007f10b245f7c0(0000) GS:ffff88083c4a0000(0000) knlGS:0000000000000000
kernel: CS:0010 DS: 0000 ES: 0000 CR0: 000000008005003b
kernel: CR2:00007ff955977380 CR3: 000000100a80b000 CR4: 00000000000006e0
kernel: DR0:0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
kernel: DR3:0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
kernel:Process qmgr (pid: 5492, threadinfo ffff88080a660000, task ffff880809577500)
kernel: Stack:
kernel:00007f10b323def0 00007f10b248ead0 00007f10b26d0f78 00007f10b248ede0
kernel:<0> ffff88080a661f68 ffffffff8106f88a 0000000000000000 0000000000000000
kernel:<0> 000000000000014c 00000000000f423d 0000000000000000 0000000000000000
kernel: CallTrace:
kernel:[<ffffffff8106f88a>] ? alarm_setitimer+0x3a/0x60
kernel:[<ffffffff8107c27e>] ? sys_alarm+0xe/0x20
kernel:[<ffffffff8100b308>] ? tracesys+0xd9/0xde
kernel: Code:89 ef e8 74 66 02 00 83 3d 15 69 b5 00 00 75 37 49 8b 84 24 70 07 00 00 48 0508 08 00 00 66 ff 00 66 66 90 fb 66 0f 1f 44 00 00 <31> c0 e9 64 fe ff ff49 8b 84 24 68 07 00 00 48 c7 80 d0 00 00
kernel: CallTrace:
kernel:[<ffffffff8106f769>] ? do_setitimer+0x209/0x220
kernel:[<ffffffff8106f88a>] ? alarm_setitimer+0x3a/0x60
kernel:[<ffffffff8107c27e>] ? sys_alarm+0xe/0x20
kernel:[<ffffffff8100b308>] ? tracesys+0xd9/0xde
abrt-mp-oops: Reported 1 kernel oopses to Abrt

2.内核软死锁(soft lockup)bug原因分析
Soft lockup名称解释:所谓,soft lockup就是说,这个bug没有让系统彻底死机,但是若干个进程(或者kernel thread)被锁死在了某个状态(一般在内核区域),很多情况下这个是由于内核锁的使用的问题。
Linux内核对于每一个cpu都有一个监控进程,在技术界这个叫做watchdog(看门狗)。通过ps –ef | grep watchdog能够看见,进程名称大概是watchdog/X(数字:cpu逻辑编号1/2/3/4之类的)。这个进程或者线程每一秒钟运行一次,否则会睡眠和待机。这个进程运行会收集每一个cpu运行时使用数据的时间并且存放到属于每个cpu自己的内核数据结构。在内核中有很多特定的中断函数。这些中断函数会调用soft lockup计数,他会使用当前的时间戳与特定(对应的)cpu的内核数据结构中保存的时间对比,如果发现当前的时间戳比对应cpu保存的时间大于设定的阀值,他就假设监测进程或看门狗线程在一个相当可观的时间还没有执。Cpu软锁为什么会产生,是怎么产生的?如果linux内核是经过精心设计安排的CPU调度访问,那么怎么会产生cpu软死锁?那么只能说由于用户开发的或者第三方软件引入,看我们服务器内核panic的原因就是qmgr进程引起。因为每一个无限的循环都会一直有一个cpu的执行流程(qmgr进程示一个后台邮件的消息队列服务进程),并且拥有一定的优先级。Cpu调度器调度一个驱动程序来运行,如果这个驱动程序有问题并且没有被检测到,那么这个驱动程序将会暂用cpu的很长时间。根据前面的描述,看门狗进程会抓住(catch)这一点并且抛出一个软死锁(soft lockup)错误。软死锁会挂起cpu使你的系统不可用。
如果是用户空间的进程或线程引起的问题backtrace是不会有内容的,如果内核线程那么在soft lockup消息中会显示出backtrace信息。
3.根据linux内核源码分析错误
根据我们第一部分内核抛出的错误信息和call trace(linux内核的跟踪子系统)来分析产生的具体原因。
首先根据我们的centos版本安装相应的linux内核源码,具体步骤如下:
(1)下载源码的rpm包kernel-2.6.32-220.17.1.el6.src.rpm
(2)安装相应的依赖库,命令:yuminstall rpm-build redhat-rpm-config asciidoc newt-devel
(3)安装源码包:rpm -ikernel-2.6.32-220.17.1.el6.src.rpm
(4)进入建立源码的目录:cd~/rpmbuild/SPECS
(5)建立生成源码目录:rpmbuild-bp --target=`uname -m` kernel.spec

下面开始真正的根据内核bug日志分析源码:
(1)第一阶段内核错误日志分析(时间在Dec 4 14:03:34这个阶段的日志输出代码分析,其实这部分代码不会导致cpu软死锁,主要是第二阶段错误日志显示导致cpu软死锁)
我们首先通过日志定位到相关源代码:看下面日志:Dec 4 14:03:34 BP-YZH-1-xxxx kernel: WARNING: atkernel/trace/ring_buffer.c:1988 rb_reserve_next_event+0x2ce/0x370() (Not tainted)
根据日志内容我们可以很容易的定位到kernel/trace/ring_buffer.c这个文件的1988行代码如下:WARN_ON(1)。
先简单解释一下WARN_ON的作用:WARN_ON只是打印出当前栈信息,不会panic。所以会看到后面有一大堆的栈信息。这个宏定义如下:
#ifndef WARN_ON
#defineWARN_ON(condition) ({ \
int __ret_warn_on = !!(condition); \
if (unlikely(__ret_warn_on)) \
__WARN(); \
unlikely(__ret_warn_on); \
})
#endif
这个宏很简单保证传递进来的条件值为0或者1(两次逻辑非操作的结果),然后使用分支预测技术(保证执行概率大的分支紧邻上面的指令)判断是否需要调用__WARN()宏定义。如果满足条件执行了__WARN()宏定义也接着执行一条空指令;。上面调用WARN_ON宏是传递的1,所以会执行__WARN()。下面继续看一下__WARN()宏定义如下:
#define __WARN() warn_slowpath_null(__FILE__,__LINE__)
从接下来的call trace信息中我们也确实发现调用了warn_slowpath_null这个函数。通过在linux内核源代码中搜索这个函数的实现,发现在panic.c(内核恐慌时的相关功能实现)中实现如下:
voidwarn_slowpath_null(const char *file, int line)
{
warn_slowpath_common(file, line,__builtin_return_address(0),
TAINT_WARN, NULL);
}
EXPORT_SYMBOL(warn_slowpath_null);//都出这个符号,让其他模块可以使用这个函数
同样的我们看到了warn_slowpath_common这个函数,而在call trace当中这个函数在warn_slowpath_null函数之前打印出来,再次印证了这个流程是正确的。同样在panic.c这个文件中我发现了warn_slowpath_common这个函数的实现如下:
static voidwarn_slowpath_common(const char *file, int line, void *caller,
unsigned taint, struct slowpath_args *args)
{
const char *board;

printk(KERN_WARNING "------------[ cut here]------------\n");
printk(KERN_WARNING "WARNING: at %s:%d %pS()(%s)\n",
file, line, caller, print_tainted());
board = dmi_get_system_info(DMI_PRODUCT_NAME);//得到dmi系统信息
if (board)
printk(KERN_WARNING "Hardware name:%s\n", board);//通过我们的日志信息可以发现我们硬件名称是ProLiant DL360 G7

if (args)
vprintk(args->fmt, args->args);

print_moles();//打印系统模块信息
mp_stack();//mp信息输出(call trace开始)
print_oops_end_marker();//打印oops结束
add_taint(taint);
}
分析这个函数的实现不难发现我们的很多日志信息从这里开始输出,包括打印一些系统信息,就不继续深入分析了(请看代码注释,里面调用相关函数打印对应信息,通过我分析这些函数的实现和我们的日志信息完全能够对应,其中mp_stack是与cpu体系结构相关的,我们的服务器应该是属于x86体系)。这里在继续分析一下mp_stack函数的实现,因为这个是与cpu体系结构相关的,而且这个函数直接反应出导致内核panic的相关进程。这个函数实现如下:
/*
* The architecture-independent mp_stackgenerator
*/
void mp_stack(void)
{
unsigned long stack;

printk("Pid: %d, comm: %.20s %s %s %.*s\n",
current->pid, current->comm,print_tainted(),
init_utsname()->release,
(int

‘捌’ 如何查看linux系统源码

一般在Linux系统中的/usr/src/linux*.*.*(*.*.*代表的是内核版本,如2.4.23)目录下就是内核源代码(如果没有类似目录,是因为还没安装内核代码)。另外还可从互连网上免费下载。注意,不要总到http://www.kernel.org/去下载,最好使用它的镜像站点下载。请在http://www.kernel.org/mirrors/里找一个合适的下载点,再到pub/linux/kernel/v2.6/目录下去下载2.4.23内核。
代码目录结构
在阅读源码之前,还应知道Linux内核源码的整体分布情况。现代的操作系统一般由进程管理、内存管理、文件系统、驱动程序和网络等组成。Linux内核源码的各个目录大致与此相对应,其组成如下(假设相对于Linux-2.4.23目录):
1.arch目录包括了所有和体系结构相关的核心代码。它下面的每一个子目录都代表一种Linux支持的体系结构,例如i386就是Intel CPU及与之相兼容体系结构的子目录。PC机一般都基于此目录。
2.include目录包括编译核心所需要的大部分头文件,例如与平台无关的头文件在include/linux子目录下。
3.init目录包含核心的初始化代码(不是系统的引导代码),有main.c和Version.c两个文件。这是研究核心如何工作的好起点。
4.mm目录包含了所有的内存管理代码。与具体硬件体系结构相关的内存管理代码位于arch/*/mm目录下。
5.drivers目录中是系统中所有的设备驱动程序。它又进一步划分成几类设备驱动,每一种有对应的子目录,如声卡的驱动对应于drivers/sound。
6.ipc目录包含了核心进程间的通信代码。
7.moles目录存放了已建好的、可动态加载的模块。
8.fs目录存放Linux支持的文件系统代码。不同的文件系统有不同的子目录对应,如ext3文件系统对应的就是ext3子目录。
Kernel内核管理的核心代码放在这里。同时与处理器结构相关代码都放在arch/*/kernel目录下。
9.net目录里是核心的网络部分代码,其每个子目录对应于网络的一个方面。
10.lib目录包含了核心的库代码,不过与处理器结构相关的库代码被放在arch/*/lib/目录下。
11.scripts目录包含用于配置核心的脚本文件。
12.documentation目录下是一些文档,是对每个目录作用的具体说明。
一般在每个目录下都有一个.depend文件和一个Makefile文件。这两个文件都是编译时使用的辅助文件。仔细阅读这两个文件对弄清各个文件之间的联系和依托关系很有帮助。另外有的目录下还有Readme文件,它是对该目录下文件的一些说明,同样有利于对内核源码的理解。
在阅读方法或顺序上,有纵向与横向之分。所谓纵向就是顺着程序的执行顺序逐步进行;所谓横向,就是按模块进行。它们经常结合在一起进行。对于Linux启动的代码可顺着Linux的启动顺序一步步来阅读;对于像内存管理部分,可以单独拿出来进行阅读分析。实际上这是一个反复的过程,不可能读一遍就理解。

‘玖’ 如何编译linux源代码

首先uname -r看一下你当前的linux内核版本

1、linux的源码是在/usr/src这个目录下,此目录有你电脑上各个版本的linux内核源代码,用uname -r命令可以查看你当前使用的是哪套内核,你把你下载的内核源码也保存到这个目录之下。
2、配置内核 make menuconfig,根据你的需要来进行选择,设置完保存之后会在当前目录下生成.config配置文件,以后的编译会根据这个来有选择的编译。
3、编译,依次执行make、make bzImage、make moles、make moles
4、安装,make install
5、.创建系统启动映像,到 /boot 目录下,执行 mkinitramfs -o initrd.img-2.6.36 2.6.36
6、修改启动项,因为你在启动的时候会出现多个内核供你选择,此事要选择你刚编译的那个版本,如果你的电脑没有等待时间,就会进入默认的,默认的那个取决于 /boot/grub/grub.cfg 文件的设置,找到if [ "${linux_gfx_mode}" != "text" ]这行,他的第一个就是你默认启动的那个内核,如果你刚编译的内核是在下面,就把代表这个内核的几行代码移到第一位如:
menuentry 'Ubuntu, with Linux 3.2.0-35-generic' --class ubuntu --class gnu-linux --class gnu --class os {

recordfail
gfxmode $linux_gfx_mode
insmod gzio
insmod part_msdos
insmod ext2
set root='(hd0,msdos1)'
search --no-floppy --fs-uuid --set=root 9961c170-2566-41ac-8155-18f231c1bea5
linux/boot/vmlinuz-3.2.0-35-generic root=UUID=9961c170-2566-41ac-8155-18f231c1bea5 ro quiet splash $vt_handoff
initrd/boot/initrd.img-3.2.0-35-generic
}
当然你也可以修改 set default="0"来决定用哪个,看看你的内核在第几位,default就填几,不过我用过这种方法,貌似不好用。

重启过后你编译的内核源码就成功地运行了,如果出现问题,比如鼠标不能用,usb不识别等问题就好好查查你的make menuconfig这一步,改好后就万事ok了。

最后再用uname -r看看你的linux内核版本。是不是你刚下的那个呢!有没有成就感?

热点内容
存储器主要用来 发布:2025-05-10 15:17:34 浏览:427
两台服务器怎么部署redis 发布:2025-05-10 15:16:09 浏览:903
cocoa编程 发布:2025-05-10 15:15:18 浏览:181
中控导航什么配置好 发布:2025-05-10 15:15:07 浏览:790
个人网站的数据库 发布:2025-05-10 15:10:17 浏览:119
会编程好处 发布:2025-05-10 14:58:49 浏览:480
编程的过程 发布:2025-05-10 14:58:38 浏览:343
怎么退出服务器开机硬件监控 发布:2025-05-10 14:53:37 浏览:232
长虹安卓电视关闭网络在哪里 发布:2025-05-10 14:37:04 浏览:143
ubuntuhttp服务器的搭建 发布:2025-05-10 14:33:06 浏览:38