update OS : Openthos and xv6,update some cmds

This commit is contained in:
shzhxh 2019-12-08 14:41:18 +08:00
parent 2769537389
commit 95e4bdc217
6 changed files with 114 additions and 44 deletions

View File

@ -48,11 +48,15 @@ init是第一个进程也叫root进程或所有进程的父进程。在此阶
##### init进程第一阶段
1. 依据第一个参数进行跳转,并设置环境变量
1. 依据程序名进行跳转,就是先决定要跑哪个程序
如果第1个参数是ueventd则执行`ueventd_main`,进行设备节点的创建和权限设定
argv[0]是当前运行程序的名称当前运行程序的名称有可能是init, modprobe, uenventd或watchdogd。其中modprobe、uenventd和watchdogd都是指向init的软链接
如果第1个参数是watchdogd则执行`watchdogd_main`,用于系统出问题时重启系统。
如果当前运行的程序名是modprobe则执行`modprobe_main`,应该是用来加载内核模块的。
如果当前运行的程序名是ueventd则执行`ueventd_main`,进行设备节点的创建和权限设定。
如果当前运行的程序名是watchdogd则执行`watchdogd_main`,用于系统出问题时重启系统。
如果REBOOT_BOOTLOADER_ON_PANIC则`install_reboot_signal_handlers`将一些信号的标志设置为SA_RESTART一旦监听到这些信号则执行重启操作。
@ -60,9 +64,9 @@ init是第一个进程也叫root进程或所有进程的父进程。在此阶
由于INIT_SECOND_STAGE是在is_first_stage里定义的这就确保了is_first_stage只能执行一次。
2. 挂载文件系统并创建目录
2. 挂载文件系统并创建目录Linux需要有这些文件系统才能运行
`umask(0)`用于清空文件权限。
`umask(0)`用于清空文件默认权限。这样才能保证后面代码里对文件权限的设置生效了否则有可能被umask()的设置给屏蔽掉。
在根目录上建立initramdisk所需的基本文件系统文件系统的其它部分是在随后的rc文件里建立的
@ -74,7 +78,7 @@ init是第一个进程也叫root进程或所有进程的父进程。在此阶
3. 初始化日志输出,挂载分区设备
InitKernelLogging用于初始化日志系统它首先把输入输出重定向到/sys/fs/selinux/null然后调用InitLogging初始化日志系统
InitKernelLogging用于初始化日志系统它首先把stdin,stdout,stderr重定向到/sys/fs/selinux/null这样printf或其它打印的函数都输出不了就不会引发异常了(因为在这个阶段printf函数是不能用的会引发错误)。然后调用InitLogging初始化日志系统这是把init进程的log打印到内核printk的log buffer因为这个时候没有shell不能进行通用的log输出借助内核的功能是较好的选择
DoFirstStageMount用于初始化特定设备并挂载。
@ -104,11 +108,11 @@ init是第一个进程也叫root进程或所有进程的父进程。在此阶
keyctl_get_keyring_ID用于初始化进程会话密钥。KEY_SPEC_SESSION_KEYRING表示获取当前进程的会话密钥1表示如获取不到则创建一个。
在`/dev`目录下创建文件`.booting`表示booting正在进行中(可以在init.rc里看到当booting结束会删除此文件)。
在`/dev`目录下创建文件`.booting`这个文件仅仅起到标志的作用,表示系统正在启动(可以在init.rc里看到当booting结束会删除此文件)。
property_init用于初始化属性系统并从指定文件读取属性。
> property_init调用__system_property_area_init实现其功能。
> property_init调用__system_property_area_init实现其功能。详见bionic/libc/include/sys和bionic/libc/bionic/system_properties.cpp
process_kernel_dt和process_kernel_cmdline分别处理dt(设备树)和命令行属性,设备树中参数的优先级总是高于命令行。
@ -166,23 +170,24 @@ init是第一个进程也叫root进程或所有进程的父进程。在此阶
bootmode是个全局静态变量用来标示启动模式android的启动模式分为正常开机流程和关机充电流程。
3. 触发所有的事件并不断监听新的事件
##### init进程第二阶段之服务处理
之前的工作是建立各种各样的事件并没有去触发。只有在本while循环里才真正的触发所有的事件并用epoll不断监听新的事件
init进程作为1号进程是永不退出的这里的while(true)循环就保证了这一点
如要执行关机命令,则通过`HandlePowerctlMessage()`来执行之
之前的工作是建立各种各样的事件并没有去触发。只有在本while循环里才真正的触发所有的事件并用epoll不断监听新的事件
当没有属性设置且没有Server开始运行时才通过`am.ExecuteOneCommand()`从current_executing_actions\_列表里执行一个command由于外部是一个无限循环所以current_executing_actions\_列表里的每个command都会执行一遍。这样的条件设定是为了保证属性设置和Server启动的完整性
1. 如要执行关机命令,则通过`HandlePowerctlMessage()`来执行之
当没有属性设置且没有Server开始运行时
2. 当没有属性设置且没有Server开始运行时才通过`am.ExecuteOneCommand()`从current_executing_actions\_列表里执行一个command由于外部是一个无限循环所以current_executing_actions\_列表里的每个command都会执行一遍。这样的条件设定是为了保证属性设置和Server启动的完整性。
3. 当没有属性设置且没有Server开始运行时
- 如系统不是正在关机,执行`restart_processes()`来判断当前Server是否需要重启如需重启则执行重启操作。
- 如有进程需要重启,设置`epoll_timeout_ms`的值
- 如有其它command需要执行则将`epoll_timeout_ms`设置为0以立即唤醒。
`epoll_wait`用于监听事件的产生,参数`epoll_fd`是由前面的`epoll_create1()`创建的epoll的文件描述符参数`ev`用于保存事件信息,参数`epoll_timeout_ms`是等待时间
4. `epoll_wait`用于监听事件的产生,参数`epoll_fd`是由前面的`epoll_create1()`创建的epoll的文件描述符参数`ev`用于保存事件信息,参数`epoll_timeout_ms`是等待时间
如未监听到事件则向log系统添加一条监听失败的信息如监听到事件则直接执行`ev.data.ptr()`即epoll_ctl注册时的回调函数
5. 如未监听到事件则向log系统添加一条监听失败的信息如监听到事件则直接执行`ev.data.ptr()`即epoll_ctl注册时的回调函数
#### step5: Zygote
@ -282,7 +287,7 @@ Zygote启动系统服务即ZygoteInit类里的startSystemServer方法。
系统服务运行起来后,引导完成,此时会发送开机启动广播`ACTION_BOOT_COMPLETED`
#### 附录:Android Init Language
#### 附录:init语言
详见system/core/init/README.md
@ -290,8 +295,10 @@ Zygote启动系统服务即ZygoteInit类里的startSystemServer方法。
从整体来看一个rc文件是由若干个段组成的。一个段只能是Actions或Server其中之一
- Actions其中Commands和trigger是对Actions的补充。
- Servers其中Options是对Servers的补充。
- Actions由trigger和它下面的一堆Commands组成。
- Servers由一堆Options组成。
注意Actions和Servers不能重名。如果重名了后出现的定义将会作为错误而忽略掉。
##### .rc文件
@ -301,7 +308,7 @@ init language用在.rc文件中它可能出现在系统中的多个位置。
##### Actions
Actions就是触发器加一串命令触发器用来决定是否执行一个Action。如果满足了触发器的条件且action还不在运行队列里则这个action会被加到运行队列的尾部。
Actions就是触发器(trigger)加一串命令(commands)触发器用来决定是否执行一个Action。如果满足了触发器的条件且action还不在运行队列里则这个action会被加到运行队列的尾部。
运行的格式如下:
@ -332,26 +339,49 @@ name是程序名pathname是程序所在的路径argument是程序的参数
Options是Services的修改器它们影响init进程如何运行service以及何时运行service。
- console此服务需要一个console。默认设备为`/dev/console`。也可自己指定,如`console /dev/tty0`,其中`/dev/`是可忽略的,即等同于`console tty0`。
- ctitical此服务是一个设备关键服务。如果在4分钟内退出4次设备将会重启进入recovery模式。
- disabled此服务无法通过它的类来启动必须通过它的名字来启动。
- disabled此服务无法通过它所属的类型(class)来启动必须通过它的名字来启动。这就意味着启动一个类型的服务时这种服务是不会被启动的也就是它被disable掉了。
- setenv在启动的进程里设置环境变量。
- socket创建一个unix域socket并将它的fd传给启动的进程。
- socket \<name> \<type> \<perm> [\<user> [\<group>]]
创建一个unix域socket它的名字叫/dev/socket/\<name>并将它的fd传给启动的进程。
- file打开一个文件并将它的fd传给启动的进程。
- user在执行服务前改变用户名。
- user在执行服务前改变用户(user)默认的用户是root。
- group在执行服务前改变组名。
- capabilities在执行服务的时候设置capabilities.
- seclabel在执行服务前改变为seclabel。
- oneshot当服务退出后不要重启它。
- class为服务指定所属的类。在同一个类里的服务可以同时打开或关闭。如不使用此选项明确指定服务所属的类则默认在default类里。
- class为服务指定所属的类型。在同一个类型里的服务可以同时打开或关闭。如不使用此选项明确指定服务所属的类型则默认在default里。
- animation将会包含所有启动和关闭animation所必须的服务。
- onrestart当服务重启的时候执行一条命令。
- writepid当子进程forks的时候将其pid写到给定文件中。
- priority调度service进程的优先级。
- namespace当forking一个服务的时候进入一个新的PID或挂载namespace。
- oom_score_adjust设置子进程的变量值。
- memcg.swappiness设置子进程的变量值。
- memcg.soft_limit_in_bytes设置子进程的变量值。
- memcg.limit_in_bytes设置子进程的变量值。
- shutdown设置关机的时候此service进程的行为。默认是关机进程通过传递SIGTERM和SIGKILL来杀死此服务。
##### Triggers
@ -477,10 +507,7 @@ Triggers就是个字符串用来匹配特定事件和触发一个action。分
> restarting, otherwise, it just starts the service.
`restorecon <path> [ <path>\* ]`
> Restore the file named by _path_ to the security context specified
> in the file\_contexts configuration.
> Not required for directories created by the init.rc as these are
> automatically labeled correctly by init.
> 将<path>所代表的文件恢复到安全上下文里这个安全上下文是在file_contexts配置中指定的。init.rc创建的目录不需要执行这个命令因为init会自动正确地标记它们。
`restorecon_recursive <path> [ <path>\* ]`
> Recursively restore the directory tree named by _path_ to the
@ -502,7 +529,7 @@ Triggers就是个字符串用来匹配特定事件和触发一个action。分
> Set the rlimit for a resource.
`start <service>`
> Start a service running if it is not already running.
> 如果一个服务还没有运行则启动它。
> Note that this is _not_ synchronous, and even if it were, there is
> no guarantee that the operating system's scheduler will execute the
> service sufficiently to guarantee anything about the service's status.
@ -516,7 +543,7 @@ Triggers就是个字符串用来匹配特定事件和触发一个action。分
`stop <service>`
> Stop a service from running if it is currently running.
> 如果一个服务正在运行则关闭它。
`swapon_all <fstab>`
> Calls fs\_mgr\_swapon\_all on the given fstab file.
@ -553,9 +580,7 @@ Triggers就是个字符串用来匹配特定事件和触发一个action。分
> immediately.
`write <path> <content>`
> Open the file at _path_ and write a string to it with write(2).
> If the file does not exist, it will be created. If it does exist,
> it will be truncated. Properties are expanded within _content_.
> 把<content>写到<path>里。<content>里的属性将会展开。
##### Imports
@ -564,4 +589,6 @@ Triggers就是个字符串用来匹配特定事件和触发一个action。分
#### 参考文档
- [foxleezh/AOSP](https://github.com/foxleezh/AOSP)
- 《深入理解Android卷1》邓凡平
- 《深入理解Android卷1》邓凡平
- [freshui/Android init进程分析](https://blog.csdn.net/freshui/article/details/5747199)
- [freshui/Android init脚本解析](https://blog.csdn.net/freshui/article/details/5772564)

View File

@ -138,7 +138,7 @@ binit 缓冲区缓存。binit会从一个静态数组buf中构建出一个有NBU
2. 将mepc寄存器写入main函数的地址这样执行mret指令后会从main函数开始执行。
3. 将satp寄存器写入0这样就不会开启分页机制而直接使用的物理地址。
4. 将medeleg和mideleg寄存器写入0xffff因为medeleg的低16位是有意义的(对应着16个异常)mideleg寄存器的低12位是有意义的那么这样把两个寄存器的低16位都写入1相当于是把所有的异常和中断的处理都授权给S态了。
5. 设置计时器中断。
5. 设置计时器中断。**TODO**:为什么在M态设置计时器中断
6. 将寄存器mhartid的值写入到寄存器tp。
7. 执行mret指令进入S特权级执行main函数。
@ -186,7 +186,10 @@ binit 缓冲区缓存。binit会从一个静态数组buf中构建出一个有NBU
##### 9. kvminithart
开启分页。
文件位置kernel/vm.c开启分页。
- 使用w_satp函数向satp寄存器写入内核页表其采用的是Sv39的分页方式。
- 使用sfence_vma函数刷新TLB这样才能使分页机制真正生效。
##### 10. procinit

View File

@ -141,9 +141,6 @@ commit # 从容器创建一个镜像。
cp
diff
events
exec # 在运行的容器中执行一个命令。
-i, --interactive # 始终保持STDIN打开,即使没有附加
-t, --tty # 分配一个伪TTY
export # 将一个容器文件系统输出为压缩文件。
history # 查看某个镜像下的所有层。
import
@ -197,6 +194,16 @@ docker create [options] <image> [cmd] [args] # 创建容器。实际上是为指
-v, --volume list # 本地目录挂载到容器里
```
##### exec
```
docker exec # 在运行的容器中执行一个命令。
-i, --interactive # 始终保持STDIN打开,即使没有附加
-t, --tty # 分配一个伪TTY
```
##### load
```

5
Software/getenforce.md Normal file
View File

@ -0,0 +1,5 @@
```
getenforce # 获取selinux的当前模式
# 可能的模式有enforcing, permissive, disabled
```

View File

@ -17,7 +17,8 @@ git push [选项] [<repository> [<refspec>...]]
```
-d, --delete # 删除远程仓库的refs。refs可以一个分支也可以是一个标签。
-f, --force #
-f, --force # 看起来不是“强制推送”这么简单,具体原理待查
-u, --set-upstream # 指定默认的远程仓库
```

View File

@ -1,7 +1,34 @@
作用:查找库与软件包的神器
安装:`sudo apt install apt-file`
#### 语法
使用:
```
apt-file [options] <action> [pattern]
apt-file [options] -f <action> <file>
apt-file [options] -D <action> <debfile>
```
- 安装完后要更新数据库`apt-file update`
- 查找软件包或库的信息`apt-file search xxx`
#### 动作
```
update # 从apt-sources获取内容
search, find # 查找
list, show # 列出包里的文件
```
#### 选项
##### 模式(pattern)选项
```
-f, --from-file # 从文件读取模式,每行代表一个模式(使用"-"代表从stdin读取模式)
-D, --from-deb # 使用.deb包的文件列表作为模式
```
##### 查找选项
##### 其它选项
#### 使用
- 安装完后要更新数据库`apt-file update`