(一):linux系统根文件夹结构

Unix-like系统中的”文件系统”的概念包含两个意思,第一个是”根文件系统”,第二个是”存储类文件系统”.后者的概念基本等同于windows操作系统,而前者与windows区别较大,他并非用于存储实际文件的.根文件系统简称rootfs,他的特点为:

 1:"文件"不仅是指硬盘上的数据,他还包含不论什么设备资源.在Unix-like系统中,全部的硬件设备都被看作是文件,"文件"是内核范畴的概念,磁盘,U盘,内存,网络,甚至cpu都被内核抽象成文件.为了区别一般意义上的文件按,内核级文件被称为"设备文件"或"设备虚拟文件".这些设备文件在rootfs中能够被看到.

2:并非全部的文件夹或文件都相应磁盘上的存储空间.比方,sys,proc,dev这三个文件夹,他们相应的不是存储空间,而是设备文件,这三个文件夹中的内容由内核及相应的驱动程序维护.

3:存储类我呢见系统不能和rootfs并列存在,而仅仅能挂载到rootfs的一个子文件夹上

4:Unix-like中的"存储类文件系统"内部等同于windows的文件系统,包含文件系统类型.windows系统常见的文件系统类型包含FAT16,FAT32,NTFS,linux中也支持这些文件系统类习惯,但更常见的却是ext2,ext3,ext4,yaffs等.

Unix-like系统中,操作系统仅仅能有一个根文件系统,但能够包含多个”存储类文件系统”.运行挂载,卸载”存储类文件系统”的操作能够在terminal下使用mount和umount命令.

(二):linux启动过程

从计算机系统的角度来看,启动过程一般分为三个步骤

首先是开机,开机就是开系统開始供电,此时,硬件电路会产生一个确定的复位时序,保证CPU是最后一个被复位的器件.CPU要最后被复位的原因就是,假设CPU第一个被复位,则当CPU复位后開始运行时,其它硬件内部的寄存器状态可能还没有准备好,比方磁盘或者内存,那么就可能出现外围硬件初始化错误.

当正确完毕复位之后,CPU開始运行第一条指令,该指令所在的内存地址是固定的,这由CPU的制造者指定.不同的CPU可能由不同的地址获取指令,可是这个地址必须是固定的,这个固定地址所保存的程序往往被称为”引导程序(bootloader)”,其作用是装载真正的用户程序.

至于怎样装载,是一个策略问题,不同的CPU会提供不同的装载方式,比方有的通过普通的并口存储器,有的则通过SD卡,还有的是通过RS232接口.不管是硬件上使用何种接口装载,装载过程必须提供下面信息,详细包含:

1:从哪里读取用户程序

2:用户程序的长度是多少

3:装载完毕用户程序之后,应该跳转到哪里,即用户程序的运行入口在哪里

第二步是运行内核程序,这里所说的内核程序在上一步中指的就是”用户程序”.由于从CPU的角度来看,除bootloader之外的全部程序都是用户程序,仅仅是从软件的角度来看,用户程序被分为”内核程序”和”应用程序”,而本步运行的是”内核程序”.

内核程序初始化的时候运行的操作包含,初始化各种硬件,包含内存,网络接口,显示器,输入设备,然后建立各种内部数据结构,这些数据结构将用于多线程调度及内存的管理等.当内核初始化完毕之后,就開始运行详细的应用程序了.在普通情况下,习惯于将第一个应用程序称为”Home程序”.

第三步就是运行Home程序,比方windows的系统桌面,就是一个典型的Home程序.之所以称其为Home程序,是由于通过该程序能够方便的启动其它应用程序.

下面看一下android的启动过程.

多数基于ARM的实际硬件系统,会从并口NADN Flash芯片中的0x00000000地址处装载程序.对于一些小型嵌入式系统而言,该地址处的程序就是终于要运行的用户程序,而对于android而言,该地址出的程序还不是android程序,而是一个叫做uboot或者fastboot的程序,其作用是初始化硬件设备,比方网口,SDRAM,RS232等,并提供一些调试功能.当uboot被装载后便開始运行,他通常会先检測用户是否按下了某些特别的按键,这些特别按键是uboot在编译的时候预先约定好的,用于进入调试模式.假设用户没有按这些特别的button,则uboot就会从NAND Flash中装载linux内核,装载的地址是在编译uboot的时候预先约定好的.

linux内核被装载之后,就開始进行内核初始化的过程,步骤例如以下:

(三):Make脚本备忘

Linux系统中包含一个Make脚本的解释器,他能够读取Make脚本的内容,并运行之,Make脚本多用于自己主动编译过程,但并非说Make脚本仅仅能拥有自己主动编译.

Make脚本的基本的语法例如以下:

目标(target): 条件(prerequest)

(Tab按键) 命令

在该语法中。目标能够是随意一个字符串名称,也能够是详细文件的名称.条件能够是其它目标的名称,也能够是详细文件的名称.运行Make脚本的时候,Make解释器会检查目标和文件里包含的文件时间戳是否同样,假设不同的话,解释器就会运行Tab键后面的’命令’,命令能够是不论什么可运行程序.

自己主动编译的基本原理就是将目标文件作为”目标”,将源文件作为”条件”,因此,当源文件改动之后,目标文件的时间戳会早于源文件,于是Make解释其就会自己主动运行相关指定”命令”.此时能够将运行编译的命令作为这里的”命令”,从而达到自己主动编译的目的.

1:一个简单的Makefile文件

源代码例如以下:

#FileName Makefile
#this file is used for showing how to use makefile
$(info start working)
hello: hello.c
echo "nothing"
hello.bin: hello.c
@echo "now make hello.bin"
gcc hello.c -o hello.bin
.PHONY: he
he: hello.c
@echo "now make he"
gcc hello.c -o hello.bin

这段代码有下面特点:

1:#符号是凝视符,可用在代码中不论什么地方
2:$是函数调用符号,info是一个函数名称,作用是输出一段信息.相似的信息输出函数还包含warning,error两个函数,只是error按书运行后会终止运行并退出
3:目标定曾经不能加不论什么空格,而命令前面必须以Tab键開始
4:.PHONY关键字用于声明一个目标,被.PHONY声明的目标将总是运行其指定的命令,而假设不声明的话,则仅当目标后面的条件变动之后才运行
5:命令前面的@符号的作用是,不显示被运行的命令.由于默认情况下,Make解释器在运行命令的时候会打印出运行的命令
6:对于hello.bin目标,该目标本身就是一个文件,其依赖的文件是hello.c文件.因此当hello.c文件被改动后,将会运行gcc命令又一次对该c文件编译,并输出hello.bin文件.

要运行以上脚本,能够运行下面命令:

$make -f Makefile hello

在该命令中,-f用于指定要运行的脚本文件名.假设不指定文件名,则解释器会自己主动从当前文件夹下寻找名称为Makefile的脚本文件.

2:变量的定义和赋值

Makefile中的变量不须要单独定义,可直接赋值,常见的赋值方式有:

Make解释器运行脚本的过程可分为两个步骤:

1:装载Makefile及Makefile中include的其它Makefile.装载全然部相关的脚本文件之后,系统内部会创建一个图,该图描写叙述了各个Makefile的依赖关系.

2:依据用户指定的target找出该target的全部依赖关系,并推断依赖条件中的文件的时间戳.假设时间戳较新,就開始运行taget中所相应的命令.

而对于变量定义和赋值,解释器会依据不同的赋值方式选择是马上赋值还是延迟赋值,赋值过程也成为展开过程.所谓马上赋值,是指在读取脚本的时候就给变量进行赋值。而延迟赋值,是指读取的时候暂不赋值,仅仅有在运行脚本的时候用到了该变量,才对其进行赋值.不同的赋值方式相应的展开时机:

3:条件控制语句

Make脚本的条件控制可分为两类,一类是在解释器解析脚本文件的时候处理,还有一类是在运行脚本的时候处理.

下面看第一类条件控制语句的语法模型,例如以下代码:

if-condition
text if the condition is true
endif
//或者
if-condition
text if the condition is true
else
text if the condition is false
endif

当中,condition仅仅能进行两种推断,一种是推断表达式是否相等,还有一种是推断表达式是否被定义,例如以下:

1: ifdef var:推断变量是否被定义过.

2:ifndef var:与ifdef相反,推断变量是否还没有被定义

3:ifeq test:推断表达式test是否相等,表达式可写成”a” “b”或(a,b)

4:ifneq test,与ifeq相反

4:宏定义

Make 脚本中的函数,按被调用的方式分为三类:

第一类是内置函数,即Make解释器内部定义好的函数,在不论什么脚本文件里可直接调用,调用的格式为:

$(fname,param...)

fname是函数的名称,param是參数,多个參数用逗号隔开

第二类是用户定义的,带參数的函数,使用define关键字进行定义,调用的格式为:

$(call fname.param...)

call是调用的关键字, fname代表函数的名称,param是函数參数,多个參数使用逗号分隔.

第三类也是用户定义的,但不带參数,该类函数也称之为宏,其调用格式为:

$(fname)

既不使用call关键字,也不包含參数.

用户函数的定义方式例如以下:

define fname
//各种详细的命令
endef

在自己定义函数中,命令钱不须要加Tab键,由于当宏被展开的时候,Make解释器会自己主动在没一行命令前加Tab键.函数内部使用(n)代表调用函数时的參数,n代表自然数,(0)代表函数名称本身,$(1)代表第一个參数.

举个样例:

define showFirstName
@echo $(1)
endef
.PHONY: name
name:
$(call showFirstName,yuandan,ferr)

这段代码中定义了函数showFirstName,其作用是将传入的第一个參数返回给调用者.使用make name命令运行以上脚本,运行结果为:

$ make name
yuandan

经常使用的内置函数:

​(1):字符串操作函数

内置的经常使用的字符串函数如表:

(2):文件名操作

用于处理文件路径,名称的经常使用函数:

(3):过程控制函数

在C语言中if/else是语法本身定义的关键字,而脚本的过程控制确实由函数完毕的.

过程控制函数表:

5:内置符号和变量

Make解释器内部定义了一些特别的符号和一些特别名称的变量,在编写用户脚本时,能够直接使用这些符号,变量,而不须要定义.

(1):内置符号

(2):内置变量

由于Make脚本主要是用于对C/C++源代码的编译,因此,其内部也定义了一些专用于C/C++编译的变量.

6:模板目标

假设当前有一个C源代码的项目,当中包含3个C源文件,名称分别为f1.c,f2.c,main.c,当中f1和f2中定义了两个函数,main.c中会使用这两个函数,然后能够编写一个脚本文件,脚本源代码例如以下:

.PHONY: test
test: f1.o f2.o main.o
gcc -o main.bin f1.o f2.o main.o
f1.o: f1.c
gcc f1.c f1.o
f2.o: f2.c
gcc f2.c f2.o
main.o: main.c
gcc main.c -c main.o

当源代码数量较多,则脚本文件的定义就会变得繁琐起来.这样我们使用一种”模板”来定义目标,使用模板目标后,以上的脚本能够简化为:

OBJ = f1.o f2.o f3.o
.PHONY: test
test: $(OBJ)
gcc $(OBJ) -o main.bin
%.o: %.c
gcc -c -o $@ $<

7:目标特定的变量赋值

在脚本文件里,当给某个变量赋值后,则之后不管Make哪个目标,该变量的值都是同样的,例如以下面代码所看到的:

CFLAGS = -c
.PHONY: tar1
tar1:
gcc $(CFLAGS) main.c
tar2 : CFLAGS=
tar2:
gcc $(CFLAGS) main.c

CFLAGS被赋值为-c,其值在整个脚本文件范围内都是有效的.比方当Make tar1的时候,就会运行gcc -c main.c.可是在tar2目标中,我们希望能够运行gcc main.c,因此能够在tar2目标中对CFLAGS变量又一次赋值,该赋值仅在tar2目标的命令中有效,这就是所谓的”目标特定”变量赋值.由于该赋值仅针对该目标.

语法上须要注意,对tar2目标的赋值不能直接写成下面形式:

tar2 : CFALGS =
gcc $(CFLAGS) main.c

而是必须分开写,即把目标变量赋值和目标规则分开写.

第一章--linux基础的更多相关文章

  1. python第一章计算机基础

    第一章 计算机基础 1.1 硬件 计算机基本的硬件由:CPU / 内存 / 主板 / 硬盘 / 网卡 / 显卡 / 显示器 等组成,只有硬件但硬件之间无法进行交流和通信. 1.2 操作系统 操作系统用 ...

  2. 《零成本实现Web自动化测试--基于Selenium》第一章 自动化测试基础

    第一篇 Selenium 和WebDriver工具篇 第一章 自动化测试基础 1.1    初识自动化测试 自动化测试有两种常见方式 1.1.1 代码驱动测试,又叫测试驱动开发(TDD) 1.1.2 ...

  3. [Python笔记][第一章Python基础]

    2016/1/27学习内容 第一章 Python基础 Python内置函数 见Python内置函数.md del命令 显式删除操作,列表中也可以使用. 基本输入输出 input() 读入进来永远是字符 ...

  4. 第一章 jQuery基础

    第一章jQuery基础 一.jQuert简介 1.什么是jQuery jQuery是javaScript的程序库之一,它是javaScript对象和实用函数的封装. jQuery是继Prototype ...

  5. web前端学习python之第一章_基础语法(二)

    web前端学习python之第一章_基础语法(二) 前言:最近新做了一个管理系统,前端已经基本完成, 但是后端人手不足没人给我写接口,自力更生丰衣足食, 所以决定自学python自己给自己写接口哈哈哈 ...

  6. web前端学习python之第一章_基础语法(一)

    web前端学习python之第一章_基础语法(一) 前言:最近新做了一个管理系统,前端已经基本完成, 但是后端人手不足没人给我写接口,自力更生丰衣足食, 所以决定自学python自己给自己写接口哈哈哈 ...

  7. UNIX环境高级编程--第一章 UNIX基础知识

    第一章 UNIX基础知识 1.2 UNIX体系结构   从严格意义上说,可将操作系统定义为一种软件,它控制计算机硬件资源,提供程序运行环境.我们将这种软件称为内核(kernel),因为 它相对较小,且 ...

  8. CentOS 7.4 初次手记:第一章 Linux守护进程(daemon)

    第一节 init & sysvinit 6 I sysvinit 运行顺序... 6 II Sysvinit和系统关闭... 7 III Sysvinit 的小结... 7 IV 运行级别.. ...

  9. Linux内核分析——第一章 Linux内核简介

    第一章   Linux内核简介 一.Unix的历史 1.Unix系统成为一个强大.健壮和稳定的操作系统的根本原因: (1)简洁 (2)在Unix中,很多东西都被当做文件对待.这种抽象使对数据和对设备的 ...

随机推荐

  1. JDBC更新10W级以上数据性能优化

    随笔缘由: 系统完成到一定程度,少不了要往数据库中添加大量数据进行性能测试. 我用程序做数据10W条,使用jdbc批更新的API,发现每次只能插入2W多条记录. 一番小小研究,觉得总结一下可能有些意义 ...

  2. SQL server 上机练习题

    首先创建一个数据库,里面有 登录表 学生表   课程表   选课表 成绩表 1. 查询Student表中的所有记录的Sname.Ssex和Class列.2. 查询教师所有的单位即不重复的Depart列 ...

  3. 计算型属性 vs 懒加载

    只实现 getter 方法的属性被称为计算型属性,等同于 OC 中的 ReadOnly 属性 计算型属性本身不占用内存空间 不可以给计算型属性设置数值 计算型属性可以使用以下代码简写 var titl ...

  4. iOS App Crash原理分析

    预备知识:OS X系统分析 1.内核XNU是Darwin的核心,也是整个OS X的核心.XNU本身由以下几个组件构成: Mach微核心 BSD层 libKern I/O Kit 此外,内核是模块化的, ...

  5. C++标准库 vector排序

    前天要做一个对C++ STL的vector容器做一个排序操作,之前一直把vector当做一个容量可自动变化的数组,是的,数组,所以打算按照对数组进行排序的方法:用快速排序或是冒泡排序等算法自己写一个排 ...

  6. Pycharm中通过扩展工具添加QTDesigner

    1.在电脑中找到Designer.exe的安装目录: 2.在pycharm中打开file->Settings->Tools->External Tools进行配置: 配置如下图所示: ...

  7. CentOS下安装微软雅黑字体

    CentOS下安装微软雅黑字体   微软雅黑下载地址:http://download.csdn.net/detail/u012547633/9796219 1.先从你本机 C:\Windows\Fon ...

  8. CF 429B B.Working out (四角dp)

    题意: 两个人一个从左上角一个从左下角分别开始走分别走向右下角和右上角,(矩阵每个格子有数)问到达终点后可以得到的最大数是多少,并且条件是他们两个相遇的时候那个点的数不能算 思路: 首先这道题如果暴力 ...

  9. 迷宫问题 POJ - 3984 (搜索输出路径)

    题目大意 题目不需要大意,poj居然还有中文题 鸣谢 特别鸣谢ljc大佬提供的方法!!! 解法 我们可能输出个最短路径的长度比较简单,但是输出最短路径真的是没有做过,这里有一种简单的方法 因为我们的d ...

  10. TestNG超时测试

    用@Test(timeOut = XXX) 指定超时时间,单位是毫秒 package com.janson; import org.testng.annotations.Test; public cl ...