• 补充知识:Linux的架构设计说明

    Android基于Linux
    服务器君一共花费 38.311 ms 进行了 3 次数据库查询,努力地为您提供了这个页面。
    广告很萌的

    前面小节 从Android架构图看开发所需的知识点 里谈到,Android是基于Linux内核的,所以有必要了解一下Linux的架构(感谢Vamei总结的资料)。

    Linux的架构介绍

    以下图为基础,先说明Linux的架构(architecture)。

    最内层是硬件,最外层是用户常用的应用,比如 Firefox 浏览器,evolution查看邮件,一个计算流体模型等等。硬件是物质基础,而应用提供服务。但在两者之间,还要经过一番周折。

    还记得Linux启动。Linux首先启动内核 (kernel),内核是一段计算机程序,这个程序直接管理管理硬件,包括CPU、内存空间、硬盘接口、网络接口等等。所有的计算机操作都要通过内核传递给硬件。

    为了方便调用内核,Linux将内核的功能接口制作成系统调用(system call)。系统调用看起来就像C语言的函数,你可以在程序中直接调用。Linux系统有两百多个这样的系统调用。用户不需要了解内核的复杂结构,就可以使用内核。

    系统调用是操作系统的最小功能单位。一个操作系统,以及基于操作系统的应用,都不可能实现超越系统调用的功能。一个系统调用函数就像是汉字的一个笔画。任何一个汉字都要由基本的笔画(点、横、撇等等)构成,就像你不能臆造笔画一样。

    在命令行中输入$man 2 syscalls可以查看所有的系统调用。你也可以通过$man 2 read来查看系统调用read()的说明。在这两个命令中的2都表示我们要在2类(系统调用类)中查询 (具体各个类是什么可以通过$man man看到)。

    系统调用提供的功能非常基础,所以使用起来很麻烦。一个简单的给变量分配内存空间的操作,就需要动用多个系统调用。Linux定义一些库函数(library routine)来将系统调用组合成某些常用的功能。上面的分配内存的操作,可以定义成一个库函数(像malloc()这样的函数)。再比如说,在读取文件的时候,系统调用要求我们设置好所需要的缓冲。我可以使用Standard IO库中的读取函数。这个读取函数既负责设置缓冲,又负责使用读取的系统调用函数。使用库函数对于机器来说并没有效率上的优势,但可以把程序员从细节中解救出来。库函数就像是汉字的偏旁部首,它由笔画组成,但使用偏旁部首更容易组成字,比如"铁"。当然,你也完全可以不使用库函数,而直接调用系统函数,就像“人”字一样,不用偏旁部首。

    实际上,一个操作系统要称得上是UNIX系统,必须要拥有一些库函数,比如ISO C标准库,POSIX标准等。

    Shell

    Shell是一个特殊的应用。很多用户将它称为命令行。shell是一个命令解释器(interpreter),当我们输入“ls -l”的时候,它将此字符串解释为

    1. 在默认路径找到该文件(/bin/ls)
    2. 执行该文件,并附带参数"-l"。

    我之前用>表示重新定向,用|表示管道,也是通过shell解释&或者|的含义。Shell接着通过系统调用指挥内核,实现具体的重定向或者管道。在没有图形界面之前,shell充当了用户的界面,当用户要运行某些应用时,通过shell输入命令,来运行程序。Shell是可编程的,它可以执行符合shell语法的文本。这样的文本叫做shell脚本(script)。可以在架构图中看到,shell下通系统调用,上通各种应用,同时还有许多自身的小工具可以使用。Shell脚本可以在寥寥数行中,实现复杂的功能。

    UNIX的一条哲学是让每个程序尽量独立的做好一个小的功能。而shell充当了这些小功能之间的“胶水”,让不同程序能够以一个清晰的接口(文本流)协同工作,从而增强各个程序的功能。这也是Linux老鸟鼓励新手多用shell,少用图形化界面的原因之一。

    Shell也有很多种,最常见的是bash,另外还有sh、csh、tcsh、ksh。它们出现的年代不同,所支持的功能也有差异。

    一个shell对应一个终端 (terminal)。曾经来说,终端是一个硬件设备,用来输入并显示输出。如今,由于图形化界面的普及,终端往往就像上图一样,是一个图形化的窗口。你可以通过这个窗口输入或者输出文本。这个文本直接传递给shell进行分析解释,然后执行。

    最后,我们进入一般的应用。应用是一个程序,它可以

    1. 直接调用系统函数
    2. 调用库函数
    3. 运行shell脚本

    这些应用可以由多种语言开发,最常见的是C语言。

    进程与库

    用户使用C或者C++编写的程序,将编译成机器码,运行成为一个进程(process)。每个进程都会有一个自己的进程空间。进程空间存活于内核空间之外的用户空间(user space)。进程空间中包含程序的代码和数据。不同进程的进程空间相互独立。进程间如果想要相互交流,需要借用特殊的进程间通信(IPC)机制。进程空间中有栈(stack)和堆(heap)。当执行到新的函数调用时,栈顶会增加一帧(stack frame),用于记录该函数的数据和返回地址。当函数执行完成时,该帧会弹出,并根据返回地址接着执行母程序的指令。堆中的空间由程序自由分配。

    Linux的程序大多是C和C++编写。代码被编译为机器码,以便计算机理解。常用的代码被编译成库(library)。程序员可以从自己的程序中调用库函数,来重复利用已有代码。程序中调用库函数时,库中包含的机器代码会加载入程序对应的进程空间。

    小结

    Linux利用内核实现软硬件的对话。通过系统调用的这个接口,Linux将上层的应用与下层的内核分离,隐藏了底层的复杂性,也提高了上层应用的可移植性。库函数利用系统调用创造出模块化的功能,

    Shell则提供了一个用户界面,并让我们可以利用shell的语法编写脚本,以整合程序。

更多 推荐条目

Welcome to NowaMagic Academy!

现代魔法 推荐于 2013-02-27 10:23   

本章最新发布
随机专题
  1. [PHP程序设计] PHP中的Hash算法 3 个条目
  2. [计算机算法] TAOCP与算法 12 个条目
  3. [PHP程序设计] htaccess 设置技巧 6 个条目
  4. [JavaScript程序设计] jQuery与表单操作 2 个条目
  5. [运维管理] 防火墙原理与应用 5 个条目
  6. [运维管理] 路由器与交换机 4 个条目
  7. [数据库技术] MySQL常用自带函数 3 个条目
  8. [移动开发] Android加载器Loaders 5 个条目
  9. [数据结构] 散列表(哈希表) 13 个条目
  10. [计算机算法] 从双端队列引出的卡特兰数 3 个条目
  11. [Python程序设计] Django Web环境配置 2 个条目
  12. [Linux操作系统] 基本 Linux Shell 命令 2 个条目
窗口 -- [博客]