Linux的一些基础概念小笔记

[TOC]

资料整理自《嵌入式Linux应用程序开发标准教程》.

文件系统

目录与分区

Windows文件系统是以驱动器的盘符为基础的, 而且每一个目录与相应的分区对应, 例如“E:\workplace”是指此文件在E盘这个分区下. 而Linux恰好相反, 文件系统是一个数, 且他的所有文件和外部设备(硬盘、光驱等)都是以文件的形式挂在这个文件树上的, 例如“/user/loacl”. ……总之, 在Windows下, 目录结构属于分区; Linux下, 分区属于目录结构.

说来说去, 最后一句是重点.

然后要注意Linux的路径用’/‘(slash)分割, Windows的用’\’(back-slash).

root权限

对root的最强烈印象来自安卓手机.

root的默认主目录在”/root”下, 而其他普通用户的目录在”/home”下. root的权限极高, 甚至可以修改Linux内核, 因此建议初学者要慎用root权限……

文件系统

现在的Linux用的默认文件系统基本就是ext3文件系统, 之前用的是ext2文件系统. swap文件系统是作为交换分区使用的. NFS是网络文件系统, ISO9660是光盘文件系统.

Linux中的文件类型与Windows有显著的区别. 其中最显著的区别是在与Linux对目录和设备都当作文件来进行处理, 这样就简化了对各种类型设备的处理, 提高了效率. Linux中主要的文件类型分为4种: 普通文件, 目录文件, 链接文件和设备文件.

Linux对目录和设备都当作文件来进行处理这说的就是Unix的”一切皆文件”吗?

Linux中文件的拥有者可以把文件的访问属性设成3种不同的访问权限: 可读(r), 可写(w)和可执行(x). 文件又有3个不同的用户级别: 文件拥有者(u), 所属的用户组(g)和系统里的其他用户(o). Linux中的文件属性用一个字符串表示, 包含的信息有文件类型, 还有三个用户级别的访问权限.

文件属性字符串的第一个字符表示文件的类型, 有这么几类:

  • “-“表示普通文件.
  • “d”表示目录文件.
  • “l”表示链接文件.
  • “c”表示字符设备.
  • “b”表示块设备.
  • “p”表示命名管道, 比如FIFO文件…?
  • “f”表示堆栈文件, 比如LIFO文件…?
  • “s”表示套接字.

比如,

1
- rwx rwx rwx

这个文件表示对三个用户级别都可读性可执行的一个普通文件.

这个字符串在用Emacs的时候会看到, 原来是这个意思.

shell

当用户在命令行下工作时, 不是直接同操作系统内核交互信息的, 而是又命令解释器接收命令, 分析然后在传给相关的程序. shell是一种Linux中的命令行解释程序, 就如同command.com是DOS下的命令解释程序一样, 为用户提供使用操作系统的接口.

这个解释很好, 跟command.com的对照也很合适, shell就是一种命令行解释程序, 这也解释了为什么会有不同的shell(BASH, c-shell等).

shell是命令语言, 命令解释程序及程序设计语言的统称. 它不仅拥有自己内建的shell命令集, 同时也能被系统中其他应用程序所调用.

shell的命令行是Linux在用户看来的最大特性, 很多命令都是函数式的, 输入函数名, 函数对象还有参数, 然后执行. 很多命令都会引发你去思考这个是怎么实现的. 操作是繁琐的, 不过的确是真正用来开发的系统.

gcc

GNU Compiler Collection是GNU项目中符合ANSI C标准的编译系统, 能够编译如C, C++, Objective-C, Java, Fortran, Pascal, Modula-3和Ada等多种语言, 而且gcc是一个交叉平台编译器, 它能够在当前的CPU平台上为不同体系结构的硬件平台开发软件.

gcc还是牛逼的很, 网上说的Windows也能用.

编译流程

gcc的编译流程分为4个步骤, 分别是:

  • 预处理(Pre-Processing), 会生成.i文件;
  • 编译(Compiling), 生成.o文件;
  • 汇编(Assembling), 生成.s文件;
  • 链接(Linking), 生成可执行文件.

之前都没有印象的是预处理这个过程.

在预处理阶段, 对包含头文件(#include)和宏定义(#define, #ifdef)等编译预处理命令进行处理.

看来用Linux写代码的确是可以接触到更多的信息, 这些原理性的东西其实我想还是比较重要的.

在成功编译后, 就进入了链接阶段. 这里涉及一个重要的概念: 函数库. 函数库有静态库和动态库两种. 静态库是指编译链接时, 将库文件的代码全部加入可执行文件, 因此生成的文件比较大, 但在运行时就不需要库文件了. 其后缀通常为”.a”. 动态库与之相反, 在编译链接时并没有将库文件的代码加入可执行文件, 而是在程序执行的时候加载库, 这样可以节省系统开销. 一般动态库的后缀是”.so”. gcc在编译时默认使用动态库.

这个以前真不知道.

编译选项

gcc指令的一般格式为: gcc [opt] file_to_be_compiled [opt][output_file].

gcc有超过100多个可用选项, 主要包括总体选项, 告警和出错选项, 优化选项和体系结构相关选项.

100好多啊, 这里列出几个来:

选项 含义
-c 只编译不链接, 产生目标文件”.o”
-S 只编译不汇编, 生成汇编代码
-E 只进行预处理, 生成”.i”文件
-g 在可执行程序中包含标准调试信息
-o file 将file文件指定为输出文件

gdb

gdb(GNU debugger?)是调试工具, 设断点还有单步运行的功能都有. 然后要用gdb在必须在gcc的编译选项中加入”-g”插入调试信息. 这就是IDE里面的debug模式跟release模式之分了吧.

make

make工程管理器就是个”自动编译管理器”, 这里的”自动”是指它能够根据文件时间戳自动发现更新过的文件而减少编译的工作量, 同时, 它通过读入makefile文件的内容来执行大量的编译工作.

就是指的增量编译(incremental compiling)吧, IDE大项目编译基本就用这个命令, 不过make是更底层更灵活的.

makefile里面写的是一系列的编译规则, 里面可以使用局部变量, 这个复杂度就可大可小了, 这么一说肯定不是一个简单的东西. 因此这里又会有用autotools工具集辅助生成makefile这一说.