Linux系统基础知识
1 基本的编译命令
多数UNIX平台都通过CC调用他们的C编译程序.除标准和CC以外,LINUX和FREEBSD还支持gcc. 基本编译命令如下:
-c 生成对象文件的编译(*.obj)当编译几个独立的模块时,当链接程序将其链接在一起时,可以使用该选项,而不是链接成可执行文件,如: $cc -c hello.c ===> hello.o $cc hello.o -o 允许用户指定输出文件名,如 $cc hello.c -o hello.o or $cc hello.c -o hello -g 指明编译程序在编译的输出中应产生调试信息.调试试信息在调试程序或程序异常退出后引用源代码和变量名core可用于文件. -D 允许从编译程序命令中定义宏符号 有两种情况:一种是使用-DMACRO,相当于在程序中使用#define MACRO ,另一种是用-DMACRO=A,相当于程序中的#define MACRO A. 如下代码: #ifdefine DEBUG printf("debug message\n"); #endif 可以添加到编译中-DDEBUG参数,执行程序打印编译信息 -I 可指定查找include文件的其他位置.例如,如果有的话include文件位于一个特殊的地方,如/usr/local/include,此选项如下: $cc -c -I/usr/local/include -I/opt/include hello.c 此时,目录搜索将按给定的顺序进行. -E 该选项相对标准,允许修改命令,使编译程序将预处理的C文件发送到标准输出,而不实际编译代码.查看C预处理伪指令和C宏是非常有用的.可能的编译输出可以重新定向到文件,然后用编辑程序分析: $cc -c -E hello.c >cpp.out 此命令使include文件和程序预处理并重定向到文件cpp.out.以后可以用编辑程序或者分页命令来分析这个文件,确定最终的C语言代码看起来怎么样. -o 优化选项, 这个选项不是标准的 -O和 -O1指定1级优化 -O2 指定2级优化 -O3 指定3级优化 -O0指定不优化 $cc -c O3 -O0 hello.c 多次优化时,以最后一次为准!!! -Wall 最高级别使用GNU专门用于显示警告的编译程序!! $gcc -Wall hello.c -L指定连接库的搜索目录,-l(小写L)指定连接库的名称 $gcc main.o -L/usr/lib -lqt -o hello 上述命令将目标文件的目标文件main.o与库qt相连接,连接时会到/usr/lib找到这个库文件.也就是说-L与-l一般要成对出现.
2 关于镜像和分区
2.1 镜像和分区之间的关系是什么?
分区是一个单独存储镜像的地址空间。直接访问搜索地址(有明确的起始地址)很容易,否则需要在文件系统中加载DDR然后访问其起始地址。
3 根文件系统
根文件系统首先启动内核时mount的第一个文件系统,内核代码映像文件保存在根文件系统中,而。
我们应该明白,文件系统和内核是完全独立的两部分。没有办法真正启动嵌入式内核下载到开发板上Linux操作系统时,文件系统无法加载。
根文件系统之所以在前面加一个根,是因为它加载了其他文件系统的根,所以没有这个根,其他文件系统就无法加载。
根文件系统包括系统启动所需的目录和关键文件,以及其他文件系统可以挂载(mount)必要的文件。
init应用程序必须在根文件系统上运行; 根文件系统提供根目录/; linux根文件系统/etc/fstab本文件中; shell命令程序必须在根文件系统上运行,例如ls、cd等命令; 总之:一套linux系统,只有核心本身不能工作,必须rootfs(上的etc配置文件在目录中,/bin /sbin等目录下的shell命令和/lib目录下的库文件等···)只有配合才能工作。
3.1 根文件系统各常用目录简介
通常,根文件系统至少包括以下目录:
/etc存储重要的配置文件。 /bin/:存储常用且开机时必须用到的执行文件。 /sbin/:存储启动过程中所需的系统执行文件。 /lib/:存储/bin/及/sbin/执行文件所需的链接库,以及Linux核心模块。 /dev/:存储设备文件。
注:五个目录必须存储在根文件系统中。
3.2 linux文件系统常用目录
Linux文件系统通常有以下目录:
存储所有用户都可以使用的基本命令,这些命令可以在挂接其他文件系统之前使用,因此/bin目录必须与根文件系统分区。 /bin目录中常用的命令有:cat,chgrp,chmod,cp,ls,sh,kill,mount,umount,mkdir,mknod,test等等,我们在用Busybox在生成根文件系统时bin在目录中,可以看到一些可执行的文件,即一些可用的命令。
存储系统命令在目录下,即只有管理员才能使用的命令,系统命令也可以存储在/usr/sbin,/usr/local/sbin目录下,/sbin基本的系统命令存储在目录中,用于启动系统、修复系统等bin类似的目录可以在挂接其他文件系统之前使用/sbin,所以/sbin目录必须与根文件系统分区。 /sbin目录中常用的命令有:shutdown,reboot,fdisk,fsck等等,本地用户安装的系统命令放在/usr/local/sbin目录下。
设备文件存储在目录中,设备文件存储在设备文件中Linux独特的文件类型,在Linux在系统下,以文件的形式访问各种设备,即通过读写设备文件来操作特定的硬件。例如,通过"dev/ttySAC0"通过文件可以操作串口0"/dev/mtdblock1"可以访问MTD设备的第二个分区。
各种配置文件存储在目录中PC上的Linux系统,/etc目录中有许多文件和目录。这些目录文件是可选的。它们取决于系统中的应用程序和是否需要配置文件。在嵌入式系统中,这些内容可以大大减少。
在此目录下存储共享库和可加载(驱动程序),共享库用于启动系统。文件系统中的可执行程序,如:/bin /sbin 程序在目录序。
对于每个普通用户来说,用户目录是可选的home目录中有一个以用户名命名的子目录,存储用户相关配置文件。
根据用户目录,普通用户目录为/home下面的子目录。
/usr目录的内容可以存在于另一个分区,然后在系统启动后挂接根文件系统/usr目录下。存储共享和只读的程序和数据,表示/usr目录中的内容可以在多个主机之间共享,主要符合FHS标准的。/usr文件应只读,与其他主机相关的可变文件应保存在其他目录中,如/var。/usr嵌入式中可以减少目录。
与/usr相反,/目录var可变数据存储在目录中,如spool目录(mail,news),log文件,临时文件。
这是一个空目录,录proc文件系统的挂接点,proc文件系统是一个没有实际存储设备的虚拟文件系统。内部目录和文件由内核临时生成,用于表示系统的运行状态,也可以操作文件控制系统。
用于临时挂载文件系统的挂接点通常是空目录,也可以在其中创建空子目录,如/mnt/cdram /mnt/hda1 。用于临时挂载光盘和硬盘。
用于存储临时文件,通常是空目录,有些程序需要生成临时文件/tmp所以/tmp必须存在并可访问目录。
3.1 挂载根文件系统rootfs
对于linux内核中的第一个文件系统不能通过mount命令或系统调用挂载。
从核心和用户的角度来看,根文件系统的概念linux从内核角度看,根文件系统是ootfs;从用户的角度来看,根文件系统是用户指定的根文件系统,在linux引导时通过内核参数root=指定。二者的关系是:在linux内核启动流程的后续会把用户指定的根文件系统挂载到rootfs文件系统的根目录下。 在linux内核启动过程中,最先挂载的根文件系统是rootfs
文件系统,该文件系统是一个内存文件系统,即是基于内存的,而且对用户隐藏。
3.2 linux内核如何挂载根文件系统?
在kernel_init
线程函数中会调用kernel_init_freeable()
函数,在kernel_init_freeable
函数中将调用prepare_namespace()
函数挂载指定的根文件系统。
以下三种方式,在实际linux启动过程中,linux内核将选择其中一种作为挂载根文件系统的方式。
【方式一】:如果root_device_name是mtd或者ubi类型的根设备,则调用mount_block_root()函数挂载文件系统。
【方式二】:调用initrd_load()进行早期根文件系统的挂载,如果mount_initrd为true的情况下,将执行根文件系统挂载操作。在linux内核中包含两种挂载早期根文件系统的机制:初始化RAM磁盘(initrd)是一种老式的机制。而initramfs是新的用于挂载早期根文件系统的机制。设计initrd和initramfs机制的目的:用于执行早期的用户空间程序;在挂载真正(最后的)根文件系统之前加载一些必须的设备驱动程序。
【方式三】:调用mount_root()函数进行文件系统挂载。该种方式是linux内核中比较常用的方式,在这种方式下,又包含三种文件系统挂载操作:1、nfs方式。2、Floppy方式。3、block方式。在平时开发中,常使用nfs进行网络挂载根文件系统,以便进行开发和调试。
4 Linux引导过程和运行级别
4.1 Linux的引导过程
系统启动之后,在进入init.d之前,我们先来看看系统都做了什么工作。 系统加电之后,首先进行的硬件自检,然后是bootloader对系统的初始化,加载内核。内核被加载到内存中之后,就开始执行了。一旦内核启动运行,对硬件的检测就会决定需要对哪些设备驱动程序进行初始化。从这里开始,内核就能够挂装根文件系统(这个过程类似于Windows识别并存取C盘的过程)。内核挂装了根文件系统,并已初始化所有的设备驱动程序和数据结构等之后,就通过启动一个叫init的用户级程序,完成引导进程。
4.2 运行级别(run level)
Init进程是系统启动之后的第一个用户进程,所以它的pid(进程编号)始终为1。init进程上来首先做的事是去读取/etc/目录下inittab文件中initdefault id值,这个值称为运行级别(run-level)。它决定了系统启动之后运行于什么级别。运行级别决定了系统启动的绝大部分行为和目的。这个级别从0到6 ,具有不同的功能。不同的运行级定义如下:
0 - 停机(千万别把initdefault设置为0,否则系统永远无法启动)
1 - 单用户模式
2 - 多用户,没有 NFS
3 - 完全多用户模式(标准的运行级)
4 – 系统保留的
5 - X11 (x window)
6 - 重新启动 (千万不要把initdefault 设置为6,否则将一直在重启 )
5 Linux中“/”, “./“和”…/“的含义
Linux中的文件(夹)是以树形结构表示的。
#表示根目录
/
#表示当前目录
./
#表示上一层目录
../
#表示上两级目录
../..
6 tmpfs文件系统
在平常工作中,我们经常需要查看Linux服务器磁盘挂载使用情况,可以使用df命令,但是使用此命令除了会查看到系统盘以及数据盘挂载情况,还会看到一个tmpfs也在挂载。
,tmpfs可以使用系统的内存或swap分区来存储文件。由此可见,tmpfs主要存储暂存的文件。 tmpfs默认的大小是RM的一半,假如你的物理内存是1024M,那么tmpfs默认的大小就是512M。
tmpfs 的另一个主要的好处是它闪电般的速度。因为典型的tmpfs文件系统会完全驻留在内存RAM中,读写几乎可以是瞬间的。同时它也有一个缺点tmpfs数据在重新启动之后不会保留,这点与内存的数据特性是一致的。
但是这个df查看到的挂载内存大小的数值,如果没有使用,是没有去真正占用的,只有真正在tmpfs存储数据了,才会去占用。比如,tmpfs大小是777M,如果用了10M大小,内存里就会使用真正使用10M,剩余的767M是可以继续被服务器其他程序来使用的。
适用场景:
(1)天生就是为临时目录而生的 (2)适合存储socket、session等,对于的临时数据也可以选择进行存储, (3)对于高I/O并且还需要持久化到磁盘的,需要通过其他手段,tmpfs可以提高linux系统的性能。
6.1 调整大小
[root@localhost ~]# mount -o remount,size=500M tmpfs /dev/shm
[root@localhost ~]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 2.0G 0 2.0G 0% /dev
tmpfs 500M 0 500M 0% /dev/shm
tmpfs 2.0G 13M 2.0G 1% /run
tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup
/dev/mapper/centos-root 36G 5.6G 30G 16% /
/dev/sda1 1014M 162M 853M 16% /boot
tmpfs 394M 4.0K 394M 1% /run/user/42
tmpfs 394M 48K 394M 1% /run/user/0
上面这种是临时修改,重启后会恢复为默认值,永久修改可以通过修改配置文件的方式。
[root@localhost ~]# vim /etc/fstab
~
tmpfs /dev/shm tmpfs defaults,size=777M 0 0
~
这样设置后重启会自动挂载为777M大小,永久生效。