首页 > 代码库 > Linux系统启动与内核管理(下)

Linux系统启动与内核管理(下)

从上一篇介绍了系统启动流程可以得知,在BIOS读取相关信息之后,接下来就是去找第一个可以启动的设备当中的MBR中读取Boot Loader信息,Boot Loader提供具有惨淡功能,直接加载内核信息,以及相关的控制权转交功能。启动系统必须有Boot Loader,然后才能去加载内核,Boot Loader存储于MBR当中,MBR只有512字节,其中前446字节存储Boot Loader,区区只有446自己不可能容纳较多的功能,LinuxBoot Loader的程序运行与配置项加载分成三个阶段来运行

stage1:运行Boot Loader主程序,这个程序必须安装在启动分区中,即MBR,因为MBR的空间有限,因此在MBR当中进安装Boot Loader的最小主程序,没有安装Boot Loader相关的配置文件

stage1_5:在MBR随后的扇区存放的是文件系统所需要的驱动程序

stage2:通过Boot Loader加载所有配置文件及相关的环境参数信息,这些配置文件及相关的环境都存放在磁盘分区的/boot目录下

在此大家一起回忆下系统的启动流程

POST(加电自检)-->Boot SequenceBIOSBoot Loadter-->kernel(ramdisk)rootfs

-->switchroot/sbin/init-->(/etc/inittab,/etc/init/*.conf)设定默认运行级别系统初始化脚本rc.sysinità关闭或启动对应级别的服务启动终端

 

grubGrand Unified Bootloader

grub 0.X(版本号) grub legacy(之前教老的系统用的事0.9的版本)

grub 1.x:grub2

 

grub legacy

stage1mbr

stage1_5mbr之后的扇区,让stage1中的boot loader能识别stage2所在分区上的文件系统

stage2:磁盘分区(/boot/grub/

配置文件/etc/grub/grub.confà/etc/grub.conf  此文件是个链接文件,真正的文件指向/boot/grub/grub.conf

stage2及内核通常放在一个单独的磁盘分区

 

grub的功能

    1、提供启动菜单、并提供交互接口

    a:编辑内核参数

    e:编辑模式,用于编辑菜单

    c:命令模式,交互式接口

    2、加载用户选择的内核或操作系统

 允许传递参数给内核如max_loop=100,给系统100loop设备

 可隐藏启动菜单

    3、为菜单提供了保护机制

 为编辑启动菜单进程认证(给grub设置密码,当用户进入grub编辑界面需要输入密码)

 为启用内核或操作系统进程认证(用户想进入某个系统需要输入密码)

技术分享

 

   grub的命令行接口

      help:获取帮助列表

help keyword:详细帮助信息

findhd#,#/path/to/somefile

root (hd#,#)

kernel /path/to/kernel_file:设定本次启动用到的内核文件;额外还可以添加许多内核支持使用的cmdline参数,内核的所有参数文件至/usr/share/doc/kernel-doc-2.6.32/Documentation

如:max_loop=100   selinux=0(关闭selinux) init=/bin/bash启动的程序

initrd  /pah/to/initramfs.img:设定为选定内核提供额外文件的ramdisk

boot:引导启动选定的内核

这一段过程也是当grub.conf文件损坏或丢失的修复过程

 

识别硬盘设备:

    hdhd##

    hd#:磁盘编号,用数字表示,从0开始编号代表的第一块硬盘

    #:分区标号,用数字表示,从0开始编号代表第一个分区

 (hd0,0)第一块硬盘的第一个分区

 

手动在命令行接口启动系统

    grub>root hd##

    grub>kernel  /vmlinuz-2.6.32-642.el6.x86_64 ro  root=/dev/device(此分区是“/”文件系统所在分区)

    grub>initrd  / initramfs-2.6.32-642.el6.x86_64.img

    grub>boot

 

grub.conf配置文件

# grub.conf generated by anaconda

#

# Note that you do not have to rerun grub after making changes to this file

# NOTICE:  You have a /boot partition.  This means that

#          all kernel and initrd paths are relative to /boot/, eg.

#          root (hd0,0)

#          kernel /vmlinuz-version ro root=/dev/mapper/vg0-LogVol00

#          initrd /initrd-[generic-]version.img

#boot=/dev/sda      //告诉boot所在的磁盘位置

default=0     //设定默认启动的titile的编号,从0开始

timeout=5        //等待用户选择的超时市场,单位是秒

splashimage=(hd0,0)/grub/splash.xpm.gz  //grub的背景图片

hiddenmenu  //隐藏菜单

password –md5  加密后的密码   //设定grub密码

title CentOS (2.6.32-431.el6.x86_64)  //内核标题或操作系统名称,字符串,可自由修改

         root (hd0,0)    //内核文件所在的设备对grub而言所有类型硬盘一律为hd;hd##表示第n个磁盘,最后的0表示对应磁盘的分区,格式为(hd#,#)

         kernel /vmlinuz-2.6.32-431.el6.x86_64 ro root=/dev/mapper/vg0-LogVol00 rd_NO_LUKS.UTF-8 rd_LVM_LV=vg0/LogVol00 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet //内核文件路径,及传递给内核的参数

      initrd /initramfs-2.6.32-431.el6.x86_64.img   //ramdisk文件路径

password –md5  密码串   //启动内核输入密码

 

 

grub加密

grub-md5-crypt命令(此命令是个交互式,输入明文密码,输出加密密码)

openssl paswwd –salt  “abc”    -l   abc指的是盐指定任意字符即可

 技术分享

 

 

破解root口令(5,6版本的系统)

启动系统,设置其运行级别为1,也就是所谓的单用户模式(当然grub没有设置密码,如果你不行其他人通过此方式修改root密码,可以为grub加个密码)

 

进入单用户模式:

    1、编辑grub菜单(选定要编辑的title,之后使用e命令)

    2、在选定的kernel后附加  1  |  s  |S   |single  都可以进入单用户模式

    3、在kernel所在行,键入b命令,启动系统进入单用户模式

 

grub的安装

安装grub的第一种方式

    grub-install

 安装grub stage1stage1_5/dev/sda1磁盘行(硬盘的第一个分区,通常为boot目录),并赋值grub相关文件到/boot/目录下

    grub-install  --root-directory=dir(通常为boot目录的父目录) /dev/sda  (boot所在的磁盘)

 

安装grub的第二种方式

 在命令下执行grub命令,会打开一个交互式的界面等待用户输入命令

    grub>root (hd#,#)   //指定内核所在分区安装grub

    grub>setup (hd#)

 技术分享

 

系统裁剪(自制linux

1、分区并创建文件系统

fdisk  /dev/sdb  分两个必要的区,一个挂载boot,一个挂载sysroot,将分区格式化ext4格式的文件系统

 

2、挂载

mkdir /mnt/{boot,sysroot}

mount  /dev/sdb1  /mnt/boot  

mount /dev/sdb2   /mnt/sysroot

 

3、安装grub

grub-install  --root-directory=/mnt   /dev/sdb

 

4、复制内核和intramfs文件

cp /boot/vmlinuz-2.6.32-642.el6.x86_64  /boot/initramfs-2.6.32-642.el6.x86_64.img   /mnt/boot/

 

5、创建grub.conf文件

vim  /mnt/boot/grub/grub.conf

default=0

timeout=3

title  my linux

           root (hd0,0)

            kernel /vmlinuz-2.6.32-642.el6.x86_64  root=/dev/mapper/vg0-root  root=/dev/sda2  selinux=0  init=/bin/bash

            initrd /initramfs-2.6.32-642.el6.x86_64.img

 

6、创建根下面所需要的目录

mkdir –-pv/mnt/sysroot/{etc,lib,lib64,bin,sbin,boot,home,var

    /log,usr/{bin,sbin},root,tmp,var,usr,proc,sys,dev,mnt,media}

 

7、复制bash和相关库文件

这里使用脚本完成,脚本内容如下:

#!/bin/bash

#

target=/mnt/sysroot

 

clearCmd() {

  if which $cmd &> /dev/null; then

        cmdPath=`which --skip-alias $cmd`

  else

        echo "No such command"

        return 5

  fi

}

 

cmdCopy() {

        cmdDir=`dirname $1`

        [ -d ${target}${cmdDir} ] || mkdir -p ${target}${cmdDir}

        [ -f ${target}${1} ] || cp $1 ${target}${cmdDir}

}

 

libCopy() {

        for lib in `ldd $1 | grep -o "/[^[:space:]]\{1,\}"`; do

                libDir=`dirname $lib`

                [ -d ${target}${libDir} ] || mkdir -p ${target}${libDir}

                [ -f ${target}${lib} ] || cp $lib ${target}${libDir}

        done

}

 

while true; do

  read -p "Enter a command: " cmd

  if [ "$cmd" == ‘quit‘ ] ;then

        echo "quit"

        exit 0

  fi

  clearCmd $cmd

  [ $? -eq 5 ] && continue

 

  cmdCopy $cmdPath

  libCopy $cmdPath

done

 

执行脚本移植需要用到的命令如mount,umount,ifconfig,ls,pwd,route,ip,vim等等

 

系统配置文件丢失修复

系统在引导期间,很重要的一个而过程就是init进程读取其配置文件/etc/inittab,启动系统基本服务程序及默认运行级别的服务程序完成引导,如果/etc/inittab误删除或修改错误,Linux将无法正常启动,此时,至于通过救援模式才可以解决此类问题,分两种情况

有备份文件的恢复方法:

进入救援模式,切到根下去(chroot  /mnt/sysimage) ,直接将备份文件拷贝到原目录下即可,如:cp /etc/inittab.bak  /etc/inittab

 

没有备份文件的恢复方法:

如果一些配置文件丢失或软件误删除,且无备份,可以通过重新安装软件包来恢复,首先查找到/etc/inittab属于哪一个rpm

chroot  /mnt/sysimage

rpm –qf /etc/inittab

initscripts-9.03.53-1.el6.centos.x86_64

之后挂载光盘,然后在安装initscripts-9.03.53-1.el6.centos.x86_64

rpm –ivh –replacepgks  /media/Packages/initscripts-9.03.53-1.el6.centos.x86_64

如果只提取/etc/inittab文件进行恢复,可以在挂载光盘后执行命令

rpm2cpio /media/Packages/initscripts-9.03.53-1.el6.centos.x86_64 |cpio –id

cp  ./etc/inittab   /etc/inittab

 

注意:此命令执行时不能将文件直接恢复至/etc/目录,只能提取到当前目录下,且恢复的文件名称所在路径要写完整的路径,提取文件成功后,将其复制到根分区所在的/mnt/sysimage目录下相应位置即可

 

 

内核版本

uname命令

命令格式:uname [OPTION]..

选项

-n:显示节点名称(主机名)

-r:显示内核版本号

-a:显示所有信息

-s:显示内核名称

-m:显示硬件平台

 

 

内核模块命令

 

lsmod :显示由核心已经装载的内核模块

显示的内容来自于/proc/modules文件

 

modinfo显示模块的详细描述信息

命令格式:modinfo [ -0 ]  [ -F field ]  [ -k kernel ]  [ modulename|filename... ]

选项

-n:只显示模块文件的路径

-p:显示模块参数

-aauthor作业

-ddescription描述

-llicense

示例:

modinfo ext4

 

modprobe装载或卸载内核模块

modprobe [ -r ]  [ -v ]  [ -n ]  [ -i ]  [ modulename... ]

选项

-r:卸载模块 modprobe  -r   mod_name

 

rmmod

rmmod modulesname

示例:

rmmod ext4

 

insmod 指定模块文件,不能自动解决依赖模块,必须指定绝对路径

insmod [ filename ]  [ module options... ]

insmod  `modinfo –n ext3`

 

 

/proc目录

刚刚提过/proc/modules来查看内核装载的模块,/proc目录我们最初的文件系统结构当中也讲过,该目录是系统与内核交互的一个伪文件系统接口,/proc下的每个文件名都是内核参数,目录名为内核参数节点信息

 

/proc/sys

sysctl命令用于查看或设定此目录中诸多参数

sysct         l –a  查看当前运行中的内核所有参数及值

sysctl –w path.to.parameter=value

sysctl –w kernel.hostname=xiao.com 修改内核参数,立即生效但不能永久生效要想永久生效必须将参数写到配置文件/etc/sysctl.conf

echo value> /proc/sys/path/to/parameter

ehco “xiao” > /proc/sys/kernel/hostname

 

sysctl –p 通过读取配置文件设置参数

 

 

常用的几个参数

net.ipv4.ip_forward   路由转发

kernel.hostname    主机名

vm.drop_caches     缓存    0为不清理缓存,1为清理缓存

net.ipvr.icmp_echo_ignore_all  0开启ping功能,1禁止ping功能

 

 

/sys目录

sysfs:为用户使用的为文件系统,输出识别出硬件设备的相关属性信息,也有内核对硬件特性的设定信息,有些参数是可以修改的,用于调整硬件工作特性

udev通过此路径下输出的信息动态为各设备创建所需需设备文件,udev是运行用户空间程序

 

专用工具udevadmin,hotplug

 

udev为设备创建设备文件时,会读取其实现定义好的规则文件,一般在/etc/udev/rules.d及、usr/lib/udev/rules.d目录下

 

ramdisk制作

ramdisk是一个虚拟的根文件系统,这个虚拟的根文件系统在/boot目录下以init开头的文件,他的特点是能够通过Boot Loader程序将其将在到内存当中,然后解压缩并在内存模拟一个根文件系统,这个根文件系统能够提供一个可以运行的程序,通过该程序可以加载在启动过程当中所需要的模块如(RAIDLVMSCSI),加载完成,会协助内核启动/sbin/init程序来执行后续的启动,那么如何去制作一个ramdisk

CentOS5之上,是通过mkinitrd命令来进行制作,在Centos6之后用dracut命令来制作ramdisk,具体如下:

    1、为当前正在使用的内核重新制作ramdisk文件

mkinitrd命令

mkinitrd  /boot/iniramfs-$(uname –r).img  $(uname –r)


dracut命令

    2、制作好之后通过file命令查看initramfs文件,得知是一个gizp的要文件,使用zcat initramfs通过过管道送过cpio进行接压缩查看里面的内容,展开之后发现其实就是一些类似根文件系统目录结构

zcat initramfs-2.6.32-642.el6.x86_64.img | cpio -id  解开

find . | cpio  -o –H newc  --quiet > gzip -9 /boot/myramdisk.img  归档

 技术分享

 

 

内核编译

首先想到的是为什么要编译内核,我们知道内核里包含了可以让硬件设备与软件发挥功能的信息,如果内核里面没有这些设备等信息,系统不会完整的工作的,那我们是不是可以一次性的将所有功能模块编译到内核中去,这样就可以保持目前所有的硬件设备了,如此一来,内核文件大小也变大了不少,而且有些根本不需要的东西也编译进来了,适得其反,所以我们是有选择性的进行编译,对需要的东西就行编译。

需要编译内核的情况有一下几种

    1、有新的功能需求,如支持虚拟化

    2、原来的内核非常臃肿,想对内核进行简化

    3、升级模块修复bug用来提高稳定性

    4、定制系统

    5、纯属个人学习内核编译使用

 

在编译内核之前需要充分熟知硬件设备信息,系统平台的相关信息,准备好软件开发环境及内核源代码

  1. 获取硬件设备信息

     cpu

     cat /proc/cpuinfo

     lscpu

     x86info –a

     lspci

     lsusb

     lsblk


  1.  开发环境准备

    安装开发包组

    Devlopment Tools  Server Platform Development

 

  • 获取源代码

    ftp上获取内核源代码

 

  • 内核功能的选择

    make  menuconfig 

    [ ]不启动此功能

    [M]编译成模块

    [*] 编译成核心

    注意:要保存退出,所有选定的设置会保存在.config隐藏文件中

 技术分享

  1. 编译内核步骤

   首先下载所需要的内核源代码

 通过ftp上资源进行下载或者通过网络下载www.kernel.org

 

  • 解压缩源代码文件到指定目录

    tar xf linux-3.18.41.tar.xz  -C /usr/src/

 

  • 将解压缩后生成的目录新建一个链接

    cd /usr/src

    ln -sv linux-3.18.41/ linux

 

  • 复制系统的内核配置模版文件到新内核目录下(文件在/boot目录下有一个config开头的文件)

    cp /boot/config-2.6.32-642.el6.x86_64  .

 

  • 选定配置

    make  help  获取make命令的帮助信息

    make config  遍历每个选项

    make menuconfig  打开文本串口,配置内核选项(这里需要注意的是,有些小伙伴喜欢用远程工具如xshell这时就需要注意了窗口最好最大化,其他使用screen命令打开一个新串口,以免编译到一遍是远程桌面断开)

 

    make allnoconfig 所有选择均不选择,执行结果将会保存在配置文件.config

 

  • 编译

    make  -j   #  #表示数字,指多线程编译

 

  • 安装模块

     make  modules_install

 

  • 安装内核

make  install

 

至此内核编译的过程就完成了,只需要重新启动系统,选择自己所编译的内核进入系统即可

 技术分享



编译内核扩展

make clean :保留.config配置文件,删除其他编译生成的所有文件

make mrproper :删除编译生成的所有文件,包括.config文件

make distclean:相当于mrproper  以及删除编译器备份及补丁文件

make gconfig  Gnome桌面环境使用,需要安装图形开发库

make xconfig   KDE桌面环境使用,需要安装图形开发库

make defconfig  基于内核为目标平台提供的默认配置进行配置

make allyesconfig   所有选项均回答为yes

make allnoconfig    所有选项均回答为no

 

1、只编译其中部分代码

只编译某个子目录下的相关代码

make  dir/ make driver/net/

 

2、只编译部分模块

make m=driver/net/

 

3、只编译某一个模块

make driver/net/pcnet32.ko

 

4、将编译完成的结果放置于指定的目录中

make o=/tmp/kernel

 

5、交叉编译

make  ARCH=arch_name

 

获取特定目标平台的使用帮助

make ARCH=arch_name help

make  ARCH=arm  help

 

 



本文出自 “运维生涯” 博客,请务必保留此出处http://fszxxxks.blog.51cto.com/10122713/1852907

Linux系统启动与内核管理(下)