`
arz611wr
  • 浏览: 13051 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

Linux基础学习 收藏

 
阅读更多

Linux基础学习 收藏
2011年06月24日
  Linux基础学习 收藏
  Linux启动过程综述
    内容:
    一. Bootloader
    二.Kernel引导入口
    三.核心数据结构初始化--内核引导第一部分
    四.外设初始化--内核引导第二部分
    五.init进程和inittab引导指令
    六.rc启动脚本
    七.getty和login
    八.bash
    附:XDM方式登录 作者:杨沙洲
    本文以Redhat 6.0 Linux 2.2.19 for Alpha/AXP为平台,描述了从开机到登录的
  Linux 启动全过程。该文对i386平台同样适用。
    一. Bootloader
  在Alpha/AXP平台上引导Linux通常有两种方法,一种是由MILO及其他类似的引导程序引 导,另一种是由Firmware直接引导。MILO功能与i386平台的LILO相近,但内置有基本的磁盘
  驱动程序(如IDE、SCSI等),以及常见的文件系统驱动程序(如ext2,iso9660等), firmware有ARC、SRM两种形式,ARC具有类BIOS界面,甚至还有多重引导的设置;而SRM则具
  有功能强大的命令行界面,用户可以在控制台上使用boot等命令引导系统。ARC有分区 (Partition)的概念,因此可以访问到分区的首扇区;而SRM只能将控制转给磁盘的首扇区。
  两种firmware都可以通过引导MILO来引导Linux,也可以直接引导Linux的引导代码。
  “arch/alpha/boot”下就是制作Linux Bootloader的文件。“head.S”文件提供了对
  OSF PAL/1的调用入口,它将被编译后置于引导扇区(ARC的分区首扇区或SRM的磁盘0扇区), 得到控制后初始化一些数据结构,再将控制转给“main.c”中的start_kernel(),
  start_kernel()向控制台输出一些提示,调用pal_init()初始化PAL代码,调用openboot() 打开引导设备(通过读取Firmware环境),调用load()将核心代码加载到START_ADDR(见
  “include/asm-alpha/system.h”),再将Firmware中的核心引导参数加载到ZERO_PAGE(0) 中,最后调用runkernel()将控制转给0x100000的kernel,bootloader部分结束。
  “arch/alpha/boot/bootp.c”以“main.c”为基础,可代替“main.c”与“head.S”
  生成用于BOOTP协议网络引导的Bootloader。
  Bootloader中使用的所有“srm_”函数在“arch/alpha/lib/”中定义。
  以上这种Boot方式是一种最简单的方式,即不需其他工具就能引导Kernel,前提是按照 Makefile的指导,生成bootimage文件,内含以上提到的bootloader以及vmlinux,然后将
  bootimage写入自磁盘引导扇区始的位置中。
  当采用MILO这样的引导程序来引导Linux时,不需要上面所说的Bootloader,而只需要 vmlinux或vmlinux.gz,引导程序会主动解压加载内核到0x1000(小内核)或0x100000(大
  内核),并直接进入内核引导部分,即本文的第二节。
  对于I386平台
  i386系统中一般都有BIOS做最初的引导工作,那就是将四个主分区表中的第一个可引导 分区的第一个扇区加载到实模式地址0x7c00上,然后将控制转交给它。
  在“arch/i386/boot”目录下,bootsect.S是生成引导扇区的汇编源码,它首先将自己 拷贝到0x90000上,然后将紧接其后的setup部分(第二扇区)拷贝到0x90200,将真正的内核
  代码拷贝到0x100000。以上这些拷贝动作都是以bootsect.S、setup.S以及vmlinux在磁盘上 连续存放为前提的,也就是说,我们的bzImage文件或者zImage文件是按照bootsect,setup,
  vmlinux这样的顺序组织,并存放于始于引导分区的首扇区的连续磁盘扇区之中。
  bootsect.S完成加载动作后,就直接跳转到0x90200,这里正是setup.S的程序入口。 setup.S的主要功能就是将系统参数(包括内存、磁盘等,由BIOS返回)拷贝到
  0x90000-0x901FF内存中,这个地方正是bootsect.S存放的地方,这时它将被系统参数覆盖。 以后这些参数将由保护模式下的代码来读取。
  除此之外,setup.S还将video.S中的代码包含进来,检测和设置显示器和显示模式。最 后,setup.S将系统转换到保护模式,并跳转到0x100000(对于bzImage格式的大内核是
  0x100000,对于zImage格式的是0x1000)的内核引导代码,Bootloader过程结束。
  对于2.4.x版内核
  没有什么变化。
    二.Kernel引导入口
  在arch/alpha/vmlinux.lds的链接脚本控制下,链接程序将vmlinux的入口置于 \"arch/alpha/kernel/head.S\"中的__start上,因此当Bootloader跳转到0x100000时,
  __start处的代码开始执行。__start的代码很简单,只需要设置一下全局变量,然后就跳转 到start_kernel去了。start_kernel()是\"init/main.c\"中的asmlinkage函数,至此,启
  动过程转入体系结构无关的通用C代码中。
  对于I386平台
  在i386体系结构中,因为i386本身的问题,在\"arch/alpha/kernel/head.S\"中需要更多的设置,但最终也是通过call
  SYMBOL_NAME(start_kernel)转到start_kernel()这个体系结构无关的函数中去执行了。
  所不同的是,在i386系统中,当内核以bzImage的形式压缩,即大内核方式 (__BIG_KERNEL__)压缩时就需要预先处理bootsect.S和setup.S,按照大核模式使用$(CPP)
  处理生成bbootsect.S和bsetup.S,然后再编译生成相应的.o文件,并使用 \"arch/i386/boot/compressed/build.c\"生成的build工具,将实际的内核(未压缩的,含
  kernel中的head.S代码)与\"arch/i386/boot/compressed\"下的head.S和misc.c合成到一起,其中的head.S代替了\"arch/i386/kernel/head.S\"的位置,由Bootloader引导执行
  (startup_32入口),然后它调用misc.c中定义的decompress_kernel()函数,使用 \"lib/inflate.c\"中定义的gunzip()将内核解压到0x100000,再转到其上执行
  \"arch/i386/kernel/head.S\"中的startup_32代码。
  对于2.4.x版内核
  没有变化。
    三.核心数据结构初始化--内核引导第一部分
  start_kernel()中调用了一系列初始化函数,以完成kernel本身的设置。 这些动作有的是公共的,有的则是需要配置的才会执行的。
  在start_kernel()函数中,
  输出Linux版本信息(printk(linux_banner))
  设置与体系结构相关的环境(setup_arch())
  页表结构初始化(paging_init())
  使用\"arch/alpha/kernel/entry.S\"中的入口点设置系统自陷入口(trap_init())
  使用alpha_mv结构和entry.S入口初始化系统IRQ(init_IRQ())
  核心进程调度器初始化(包括初始化几个缺省的Bottom-half,sched_init())
  时间、定时器初始化(包括读取CMOS时钟、估测主频、初始化定时器中断等,time_init())
  提取并分析核心启动参数(从环境变量中读取参数,设置相应标志位等待处理,(parse_options())
  控制台初始化(为输出信息而先于PCI初始化,console_init())
  剖析器数据结构初始化(prof_buffer和prof_len变量)
  核心Cache初始化(描述Cache信息的Cache,kmem_cache_init())
  延迟校准(获得时钟jiffies与CPU主频ticks的延迟,calibrate_delay())
  内存初始化(设置内存上下界和页表项初始值,mem_init())
  创建和设置内部及通用cache(\"slab_cache\",kmem_cache_sizes_init())
  创建uid taskcount SLAB cache(\"uid_cache\",uidcache_init())
  创建文件cache(\"files_cache\",filescache_init())
  创建目录cache(\"dentry_cache\",dcache_init())
  创建与虚存相关的cache(\"vm_area_struct\",\"mm_struct\",vma_init())
  块设备读写缓冲区初始化(同时创建\"buffer_head\"cache用户加速访问,buffer_init())
  创建页cache(内存页hash表初始化,page_cache_init())
  创建信号队列cache(\"signal_queue\",signals_init())
  初始化内存inode表(inode_init())
  创建内存文件描述符表(\"filp_cache\",file_table_init())
  检查体系结构漏洞(对于alpha,此函数为空,check_bugs())
  SMP机器其余CPU(除当前引导CPU)初始化(对于没有配置SMP的内核,此函数为空,smp_init())
  启动init过程(创建第一个核心线程,调用init()函数,原执行序列调用cpu_idle() 等待调度,init())
  至此start_kernel()结束,基本的核心环境已经建立起来了。
  对于I386平台
  i386平台上的内核启动过程与此基本相同,所不同的主要是实现方式。
  对于2.4.x版内核
  2.4.x中变化比较大,但基本过程没变,变动的是各个数据结构的具体实现,比如Cache。
    四.外设初始化--内核引导第二部分
  init()函数作为核心线程,首先锁定内核(仅对SMP机器有效),然后调用 do_basic_setup()完成外设及其驱动程序的加载和初始化。过程如下:
  总线初始化(比如pci_init())
  网络初始化(初始化网络数据结构,包括sk_init()、skb_init()和proto_init()三部分,在proto_init()中,将调用protocols结构中包含的所有协议的初始化过程,sock_init())
  创建bdflush核心线程(bdflush()过程常驻核心空间,由核心唤醒来清理被写过的内存缓冲区,当bdflush()由kernel_thread()启动后,它将自己命名为kflushd)
  创建kupdate核心线程(kupdate()过程常驻核心空间,由核心按时调度执行,将内存缓冲区中的信息更新到磁盘中,更新的内容包括超级块和inode表)
  设置并启动核心调页线程kswapd(为了防止kswapd启动时将版本信息输出到其他信息中间,核心线调用kswapd_setup()设置kswapd运行所要求的环境,然后再创建
  kswapd核心线程)
  创建事件管理核心线程(start_context_thread()函数启动context_thread()过程,并重命名为keventd)
  设备初始化(包括并口parport_init()、字符设备chr_dev_init()、块设备 blk_dev_init()、SCSI设备scsi_dev_init()、网络设备net_dev_init()、磁盘初始化及分区检查等等,device_setup())
  执行文件格式设置(binfmt_setup())
  启动任何使用__initcall标识的函数(方便核心开发者添加启动函数,do_initcalls())
  文件系统初始化(filesystem_setup())
  安装root文件系统(mount_root())
  至此do_basic_setup()函数返回init(),在释放启动内存段(free_initmem())并给内核解锁以后,init()打开 /dev/console设备,重定向stdin、stdout和stderr到控制台,最后,搜索文件系统中的init程序(或者由init=命令行参数指定的程序),并使用
  execve()系统调用加载执行init程序。
  init()函数到此结束,内核的引导部分也到此结束了,这个由start_kernel()创建的第一个线程已经成为一个用户模式下的进程了。此时系统中存在着六个运行实体:
  start_kernel()本身所在的执行体,这其实是一个\"手工\"创建的线程,它在创建了init()线程以后就进入cpu_idle()循环了,它不会在进程(线程)列表中出现
  init线程,由start_kernel()创建,当前处于用户态,加载了init程序
  kflushd核心线程,由init线程创建,在核心态运行bdflush()函数
  kupdate核心线程,由init线程创建,在核心态运行kupdate()函数
  kswapd核心线程,由init线程创建,在核心态运行kswapd()函数
  keventd核心线程,由init线程创建,在核心态运行context_thread()函数
  对于I386平台
  基本相同。
  对于2.4.x版内核
  这一部分的启动过程在2.4.x内核中简化了不少,缺省的独立初始化过程只剩下网络 (sock_init())和创建事件管理核心线程,而其他所需要的初始化都使用__initcall()宏
  包含在do_initcalls()函数中启动执行。
    五.init进程和inittab引导指令
  init进程是系统所有进程的起点,内核在完成核内引导以后,即在本线程(进程)空 间内加载init程序,它的进程号是1。
  init程序需要读取/etc/inittab文件作为其行为指针,inittab是以行为单位的描述性(非执行性)文本,每一个指令行都具有以下格式:
  id:runlevel:action:process其中id为入口标识符,runlevel为运行级别,action为动作代号,process为具体的执行程序。
  id一般要求4个字符以内,对于getty或其他login程序项,要求id与tty的编号相同,否则getty程序将不能正常工作。
  runlevel 是init所处于的运行级别的标识,一般使用0-6以及S或s。0、1、6运行级别被系统保留,0作为shutdown动作,1作为重启至单用户模式,6 为重启;S和s意义相同,表示单用户模式,且无需inittab文件,因此也不在inittab中出现,实际上,进入单用户模式时,init直接在控制台(/dev/console)上运行/sbin/sulogin。
  在一般的系统实现中,都使用了2、3、4、5几个级别,在Redhat系统中,2表示无NFS支持的多用户模式,3表示完全多用户模式(也是最常用的级别),4保留给用户自定义,5表示XDM图形登录方式。7-9级别也是可以使用的,传统的Unix系统没有定义这几个级别。runlevel可以是并列的多个值,以匹配多个运行级别,对大多数action 来说,仅当runlevel与当前运行级别匹配成功才会执行。
  initdefault是一个特殊的action值,用于标识缺省的启动级别;当init由核心激活 以后,它将读取inittab中的initdefault项,取得其中的runlevel,并作为当前的运行级
  别。如果没有inittab文件,或者其中没有initdefault项,init将在控制台上请求输入 runlevel。
  sysinit、boot、bootwait等action将在系统启动时无条件运行,而忽略其中的runlevel,其余的action(不含initdefault)都与某个runlevel相关。各个action的定义在inittab的man手册中有详细的描述。
  在Redhat系统中,一般情况下inittab都会有如下几项:
  id:3:initdefault:
  #表示当前缺省运行级别为3--完全多任务模式;
  si::sysinit:/etc/rc.d/rc.sysinit
  #启动时自动执行/etc/rc.d/rc.sysinit脚本
  l3:3:wait:/etc/rc.d/rc 3
  #当运行级别为3时,以3为参数运行/etc/rc.d/rc脚本,init将等待其返回
  0:12345:respawn:/sbin/mingetty tty0
  #在1-5各个级别上以tty0为参数执行/sbin/mingetty程序,打开tty0终端用于
  #用户登录,如果进程退出则再次运行mingetty程序
  x:5:respawn:/usr/bin/X11/xdm -nodaemon
  #在5级别上运行xdm程序,提供xdm图形方式登录界面,并在退出时重新执行
    六.rc启动脚本
  上一节已经提到init进程将启动运行rc脚本,这一节将介绍rc脚本具体的工作。
  一般情况下,rc启动脚本都位于/etc/rc.d目录下,rc.sysinit中最常见的动作就是激活交换分区,检查磁盘,加载硬件模块,这些动作无论哪个运行级别都是需要优先执行的。仅当rc.sysinit执行完以后init才会执行其他的boot或bootwait动作。
  如果没有其他boot、bootwait动作,在运行级别3下,/etc/rc.d/rc将会得到执行,命令行参数为3,即执行/etc/rc.d /rc3.d/目录下的所有文件。rc3.d下的文件都是指向/etc/rc.d/init.d/目录下各个Shell脚本的符号连接,而这些脚本一般能接受start、stop、restart、status等参数。rc脚本以start参数启动所有以S开头的脚本,在此之前,如果相应的脚本也存在K打头的链接,而且已经处于运行态了(以/var/lock/subsys/下的文件作为标志),则将首先启动K开头的脚本,以stop作为参数停止这些已经启动了的服务,然后再重新运行。显然,这样做的直接目的就是当init谋湓诵屑侗鹗保
分享到:
评论

相关推荐

    linux基础学习资料

    该文档是作者呕心沥血,多年总结出来的学习资料,值得收藏和学习。

    从Windows转向Linux教程E3000基础学习

    从Windows转向Linux教程E3000基础学习,对想学习linux的朋友提供点帮助,将我收藏的linux学习教程拿出来跟大家分享下。

    linux基础代码认知.zip

    linux基础代码认知.zip 基本的操作,适合新人学习 这个只是基础资源,做存储收藏使用 不喜勿扰

    【精品】我收藏的Linux资料全集

    从Windows转向Linux教程E3000基础学习 UbuntuManual中文版 Ubuntu-Reference-Manual(中文版) RedHat_Enterprise_Linux培训PPT Linux实用培训学习教程1.0(最终版) Linux培训文件PPT Linux命令大全 Linux命令从入门到...

    linux使用教程基础知识

    linux使用教程~有关于Linux的学习报告 小丸子帮大家总结到位了 希望可以帮助各位 点赞收藏哈!!!

    Linux电子课件,零基础学习最适合的

    很好的课件 必收藏! 本课件是关于Linux操作系统的讲解,内容丰富,容易理解

    OracleLinux相关经典收藏

    自己学习oracle,Linux过程中寻查到的相关资料。很经典。我是0基础的,所以觉得都是非常不错的东东吧。供大家学习。

    Linux组合礼包【精华】【免积分供应】

    Linux菜鸟专用资料、linux从入门到精通、Linux网络编程、Linux系统基础教程、初入Linux世界、嵌入式Linux应用程序开发详解(1-11)、Linux 指令大全、linux系统服务、UNIX常用命令、搭建一个安全的Linux服务器教程、...

    12本精彩的Linux书籍

    12本精彩的Linux书籍 1. Sed and Awk,作者Dale Dougherty and Arnold Robbins。...如果你想要你的密友或朋友学习Linux系统的话,那么装上Ubuntu并用把这本书作为礼物送给他,那么他一定会非常感激你的。

    Linux原理及应用

    这是一个Linux电子书,从基础开始,深入浅出,简单易懂,讲解全面,值得学习,也值得收藏

    Linux培训系列-旗舰书籍

    这是我收藏的关于Linux培训方面的pdf电子书,非常适合想要学习Linux的朋友, 需要的朋友赶快下载,希望对你们有帮助

    Python3学习路线图.pdf

    通过本实验将学习到 Linux 命令⾏操作,Python 基础,pillow 库的使⽤,argparse 库的使⽤。 2. 本实验仅⽤200⾏的 python 代码完成2048⼩游戏的编写。通过本实验将学习 Python 基本知识,状态机的概念,以及编写 ...

    LINUX应用技术精华

    chm格式(帮助格式)的文件,其中包含安装,学习指导,新手入门,学习方法,基础技能,系统管理与桌面应用等等,内容丰富,绝对值得收藏

    大数据学习计划.pdf

    也是我们今天就要拿出收藏已久的⼤数据学习计划。帮助你不⾛弯路,迈向 ⼤数据 1 ⼤数据应⽤离不开基础软件的⽀撑,且⼤部分⼤数据组件部署在 Linux 操作系统上的⽤户空间,也有很多组件也借鉴了Linux 操作系统的⼀ ...

    基于微信聊天机器人为入口内容收藏应用.zip

    对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】: 有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 鼓励下载和使用,并欢迎大家互相学习,共同...

    基于nodejs开发的微信小程序博客,个人博客,koa搭建,全栈项目。文章评论,小程序授权,收藏文章,blogs,面.zip

    对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】: 有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 鼓励下载和使用,并欢迎大家互相学习,共同...

    java多线程tcpsocketserver源码-Java-Book:Java学习资料整理

    --(如果不是计算机科班的,应先看看计算机基础,了解一些基本概念,有助于之后的学习) 计算机操作系统 操作系统原理及应用(Linux) LINUX Linux命令行与shell脚本编程大全 --(常用命令的介绍和脚本编写) Unix环境高级...

    毕设&课设&项目&实训-基于Python3.6+django1.11的音乐网站,附带视频播放,响应式设计,支持评论。.zip

    毕设&课设&项目&实训-基于Python3.6+django1.11的音乐网站,附带视频播放,响应式设计,支持评论,收藏和查看历史播放记录。 【项目资源】: 包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、...

    c#学习笔记.txt

    C#学习笔记(2)【大 中 小】【打印】【加入收藏】【关闭】 【收藏到新浪ViVi】【收藏到365KEY】 浏览字号:日期:2004-07-11 人气:8092 出处: write by cash(天下第七) 2002.01.20 版权所有,翻录不究 cashcao@...

    毕设&课设&项目&实训-基于thinkphp5购物平台网上美食商城管理系统项目.zip

    基于thinkphp5购物平台网上美食商城管理系统项目,可二次开发修改为名鞋商城、图书...如果基础还行,或者热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。欢迎下载,沟通交流,互相学习,共同进步!

Global site tag (gtag.js) - Google Analytics