存档

2011年10月 的存档

系统引导

2011年10月31日 1 条评论

本文基于 i386 架构分析.

计算机开机通电后 BIOS 将可启动设备(在 BIOS 里由用户设置, U盘, 硬盘, 光盘等)的第一个 扇区的 512 个字节读入内存绝对地址 0x7C00 处, 然后跳转到这个地方执行, 注意此时 CPU 处于 16 位地址的实模式.

远古时代的 Linux 的启动引导

在 boot 目录下共有三个文件 bootsect.S, setup.S, head.S 来做系统开始初始化的一些工作.

bootsect.S

bootsect.S 被编译链接后驻留在启动设备的第一个扇区的前 512 个字节处. 计算机加点启动后 BIOS 将会把 bootsect 加载到 内存 0x7C00 处并开始执行.

这个文件的主要目的是把 setup 和 system(Linux的真正代码)的代码加载到内存中.

bootsect 的执行流程如下:

  1. 用 movw 指令将 0x7C00 开始的 512 字节移动到 0x90000 处, 并跳转到 0x90000 开始执行.
  2. 从磁盘第二扇区开始读取4个扇区到 0x90200 处.
  3. 从磁盘的第扇区开始加载 0x30000(196KB) 的数据到 0x10000 处.
  4. 做完文件系统设备号的检查后, 通过 jmpi 0, SETUPSEG(0x90200) 跳转到 setup 处开始执行.

setup.S

setup 的主要目的是利用 BIOS 提供的中断服务程序(这些中断向量表存放在 0x000开始的位置, 所以 bootsect 加载 system 时候只能从 0x10000 开始) 从设备上提取内核运行所需的机器系统数据, 其中包括光标位置和显示页面, 硬盘参数表等数据, 把它们存放在 0x90000(覆盖 bootsect)开始的位置. 然后移动 system 到 0x000000, 然后设置各种参数, 为 linux 进入 保护模式做好准备.

setup 的执行流程如下:

  1. 将一些系统参数(内存, 硬盘等)存在 0x90000 处.
  2. 关闭中断(cli指令), 将 linux(system模块) 移动到 0x00000, 此时 BIOS 提供 的 16 位的中断机制已经没有了(被覆盖了).
  3. 打开 A20, 实现线性寻址.
  4. 对中断重新编程.
  5. 切换到保护模式.
  6. 跳转到(jmpi 0,8) , 8 = 0x00001000(表示0x00000的特权级, 全局描述符表)

head.S

注意, 此时开始采用 AT&T 的汇编语法,

head 的执行流程如下:

  1. 把相应的段寄存器设置为新的保护模式下的值.
  2. 重新设置中断描述符表(只是简单的初始化, 真正的中断以后再安装)
  3. 重新设置全局描述符表(段限长改为16M)
  4. 确定 A20 线是否开启, 是否含有协处理器.
  5. 以下几步非常关键, 把 main 需要的参数(三个空), L6, 和 main 压栈
  6. 然后设置分页: 开启分页功能. 在内存 0x0 处的 5K 存放一页页目录和四页页表 (此时这四页内核专用, 可寻址 16 M, 页表共用)

现代 Linux 的启动引导

Grub + kernel(): 未完待续

分类: Kernel, linux 标签: ,

常用的 bash 快捷键

2011年10月3日 2 条评论

默认的 bash 的快捷键是 Emacs 绑定的, 前两天看到一篇帖子 Bash Shell 快捷键的学习使用, 发现有一些很有用的快捷键我居然不知道, 而且我常用的一些快捷键也没有列出来, 遂把我常使用的 Bash 快捷键和上述的整理出来, 做一个记录.

注: 按照 Emacs 的习惯, Ctrl 键用 C 简写, Alt 用 M 简写. 快捷键生效, 必须把把菜单访问键盘

移动相关

C-a
和 Emacs 一样, 跳到一行的开头, 类似的 C-e 跳到一行的结尾, 这两个组合 一般是最常用的按键, 因为我常常看到很多用 Bash 的同学费劲的去找 Home 和 End, 要知道那两个键很远阿.
C-e
移动到行尾.
C-b
往回移动一个字符.
A-b
往回移动一个单词, 空格, “:”, “-” 等符号默认是单词分隔符.
C-f
往前移动一个字符.
A-f
往前移动一个单词, 分隔符同 A-b.
C-]-k
跳转到第一个 ‘k’ 出现的地方. ‘k’ 可以是任意字符.
C-xx
来回跳转, 比如 C-]-k 跳到 ‘k’ 出现的地方, 按 C-xx 跳回来.

编辑相关

C-d
删除光标所在字符.
C-h
删除光标所在位置的前一个字符.
C-backspace
同上.
A-d
删除一个单词, 单词的分隔符同上.
C-w
删除光标所在位置的前一个单词.
A-backspace
同上.
C-k
从光标开始删除到行末.
C-u
从光标开始删除到行首.
C-y
粘帖, 以上删除的字符可以通过这个指令粘帖到光标所在位置.
C-_
恢复, 以上的操作可以通过这个指令恢复.

查找

C-r
查找历史命令
C-]-k
跳转到第一个 ‘k’ 出现的地方. k可以是任意字符.

其它

C-c
结束进程.
C-l
清屏.

奇淫技巧(不常用)

C-t
交换两个字符.
A-*
补全所有匹配项.
A-.
补全上一条命令的最后一个参数.
A-<
跳到历史记录中的第一条命令.
A-\
删除光标到下一个字符的所有空格.
A-l
把光标所在的单词的大写字符变为小写.
A-u
把光标所在的单词的小写字符变为大写.
A-t
交换两个单词.

另外, 这里有一篇 飞快的使用命令行 对 history 指令和 “!” 的使用写得非常不错. 值得参考一下.

最后吐槽一下, Emacs 真他妈强大.

分类: linux, Tips 标签: