From fb791ea135ef07e069d03eb2b139a7def1e45bb5 Mon Sep 17 00:00:00 2001 From: xinqiu Date: Mon, 21 Sep 2015 16:20:56 +0800 Subject: [PATCH] Linux insides --- Booting/README.md | 10 -------- Booting/linux-bootstrap-1.md | 10 ++++---- LINKS.md | 46 ++++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 15 deletions(-) delete mode 100755 Booting/README.md create mode 100644 LINKS.md diff --git a/Booting/README.md b/Booting/README.md deleted file mode 100755 index 86747e6..0000000 --- a/Booting/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# 内核引导过程 - -本章介绍了Linux内核引导过程。你将在这看到一些描述内核加载过程的整个周期的相关文章: - -* [从引导加载程序内核](http://xinqiu.gitbooks.io/linux-inside-zh/content/Booting/index.html/linux-bootstrap-1.html) - 介绍了从启动计算机到内核执行第一条指令之前的所有阶段; -* [在内核安装代码的第一步](http://xinqiu.gitbooks.io/linux-inside-zh/content/Booting/linux-bootstrap-2.html) - 介绍了在内核设置代码的第一个步骤。你会看到堆的初始化,查询不同的参数,如EDD,IST和等... -* [视频模式初始化和转换到保护模式](http://xinqiu.gitbooks.io/linux-inside-zh/content/Booting/linux-bootstrap-3.html) - 介绍了视频模式初始化内核设置代码并过渡到保护模式。 -* [过渡到64位模式](http://xinqiu.gitbooks.io/linux-inside-zh/content/Booting/linux-bootstrap-4.html) - 介绍了过渡到64位模式的准备并过渡到64位。 -* [内核解压缩](http://xinqiu.gitbooks.io/linux-inside-zh/content/Booting/linux-bootstrap-5.html) - 介绍了内核解压缩之前的准备然后直接解压缩。 - diff --git a/Booting/linux-bootstrap-1.md b/Booting/linux-bootstrap-1.md index 5d32381..dea9965 100644 --- a/Booting/linux-bootstrap-1.md +++ b/Booting/linux-bootstrap-1.md @@ -35,29 +35,29 @@ CS selector 0xf000 CS base 0xffff0000 ``` -处理器开始在[实模式](https://en.wikipedia.org/wiki/Real_mode)工作,我们需要退回一点去理解在这种模式下的内存分割。所有 x86兼容处理器都支持实模式,从[8086](https://en.wikipedia.org/wiki/Intel_8086)到现在的Intel 64位 CPU。8086处理器有一个20位寻址总线,这意味着它可以对0到2^20 位地址空间进行操作(1Mb).不过它只有16位的寄存器,通过这个16位寄存器最大寻址是2^16即 0xffff(64 Kb)。[内存分配](http://en.wikipedia.org/wiki/Memory_segmentation) 被用来充分利用所有空闲地址空间。所有内存被分成固定的65535 字节或64 KB大小的小块。由于我们不能用16位寄存器寻址小于64KB的内存,一种替代的方法被设计出来了。一个地址包括两个部分:数据段起始地址和从该数据段起的偏移量。为了得到内存中的物理地址,我们要让数据段乘16并加上偏移量: +处理器开始在[实模式](https://en.wikipedia.org/wiki/Real_mode)工作,我们需要退回一点去理解在这种模式下的内存分割。所有 x86兼容处理器都支持实模式,从[8086](https://en.wikipedia.org/wiki/Intel_8086)到现在的Intel 64位 CPU。8086处理器有一个20位寻址总线,这意味着它可以对0到2^20 位地址空间进行操作(1Mb).不过它只有16位的寄存器,通过这个16位寄存器最大寻址是2^16即 0xffff(64 Kb)。[内存分配](http://en.wikipedia.org/wiki/Memory_segmentation) 被用来充分利用所有空闲地址空间。所有内存被分成固定的65535 bytes或64 KB大小的小块。由于我们不能用16位寄存器寻址小于64KB的内存,一种替代的方法被设计出来了。一个地址包括两个部分:数据段起始地址和从该数据段起的偏移量。为了得到内存中的物理地址,我们要让数据段乘16并加上偏移量: ``` PhysicalAddress = Segment * 16 + Offset ``` -举个例子,如果 `CS:IP` 是 `0x2000:0x0010`, 相关的物理地址将会是: +For example if `CS:IP` is `0x2000:0x0010`, the corresponding physical address will be: ```python >>> hex((0x2000 << 4) + 0x0010) '0x20010' ``` -不过如果我们让最大端进行偏移:`0xffff:0xffff`,将会是: +But if we take the biggest segment part and offset: `0xffff:0xffff`, it will be: ```python >>> hex((0xffff << 4) + 0xffff) '0x10ffef' ``` -这超出1MB65519字节。既然只有1MB在实模式中可以访问,`0x10ffef` 变成有[A20](https://en.wikipedia.org/wiki/A20_line)缺陷的 `0x00ffef`。 +which is 65519 bytes over first megabyte. Since only one megabyte is accessible in real mode, `0x10ffef` becomes `0x00ffef` with disabled [A20](https://en.wikipedia.org/wiki/A20_line). -我们知道实模式和内存地址。回到复位后的寄存器值。 +Ok, now we know about real mode and memory addressing. Let's get back to register values after reset. `CS` register consists of two parts: the visible segment selector and hidden base address. We know predefined `CS` base and `IP` value, logical address will be: diff --git a/LINKS.md b/LINKS.md new file mode 100644 index 0000000..d953b7f --- /dev/null +++ b/LINKS.md @@ -0,0 +1,46 @@ +Useful links +======================== + +Linux boot +------------------------ + +* [Linux/x86 boot protocol](https://www.kernel.org/doc/Documentation/x86/boot.txt) +* [Linux kernel parameters](https://github.com/torvalds/linux/blob/master/Documentation/kernel-parameters.txt) + +Protected mode +------------------------ + +* [64-ia-32-architectures-software-developer-vol-3a-part-1-manual.pdf](http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html) + +Serial programming +------------------------ + +* [8250 UART Programming](http://en.wikibooks.org/wiki/Serial_Programming/8250_UART_Programming#UART_Registers) +* [Serial ports on OSDEV](http://wiki.osdev.org/Serial_Ports) + +VGA +------------------------ + +* [Video Graphics Array (VGA)](http://en.wikipedia.org/wiki/Video_Graphics_Array) + +IO +------------------------ + +* [IO port programming](http://www.tldp.org/HOWTO/text/IO-Port-Programming) + +GCC and GAS +------------------------ + +* [GCC type attributes](https://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html) +* [Assembler Directives](http://www.chemie.fu-berlin.de/chemnet/use/info/gas/gas_toc.html#TOC65) + + +Important data structures +-------------------------- + +* [task_struct definition](http://lxr.free-electrons.com/source/include/linux/sched.h#L1274) + +Other architectures +------------------------ + +* [PowerPC and Linux Kernel Inside](http://www.systemcomputing.org/ppc/)