Specify language for visual improvement.

This commit is contained in:
leefige 2018-04-03 16:06:08 +08:00
parent 012434e9ee
commit 4699a9bf9a
6 changed files with 13 additions and 13 deletions

View File

@ -71,7 +71,7 @@ void main()
得到的主要汇编代码为:
```asm
```x86asm
movl count,%ecx
movl value,%eax
movl buf,%edi
@ -106,7 +106,7 @@ asm("leal (%1,%1,4),%0"
这段代码到的主要汇编代码为:
```asm
```x86asm
movl x,%eax
#APP
leal (%eax,%eax,4),%eax

View File

@ -29,10 +29,10 @@ virt addr = phy addr + 0xC0000000
ucore
的内存管理经常需要查找页表给定一个虚拟地址找出这个虚拟地址在二级页表中对应的项。通过更改此项的值可以方便地将虚拟地址映射到另外的页上。可完成此功能的这个函数是get\_pte函数。它的原型为
```
```c
pte_t *get_pte (pde_t *pgdir, uintptr_t la, bool create)
```
下面的调用关系图可以比较好地看出get\_pte在实现上流程中的位置:
下面的调用关系图可以比较好地看出get\_pte在实现上流程中的位置:
![](../lab2_figs/image007.png)
@ -90,7 +90,7 @@ virt addr = linear addr + 0xC0000000 = phy addr + 2 * 0xC0000000
```
如何保证此时内核依然能够正常工作呢其实只需让index为0的页目录项的内容等于以索引值为(KERNBASE>>22)的目录表项的内容即可。目前内核大小不超过
4M 实际上是3M因为内核从 0x100000开始编址这样就只需要让页表在0\~4MB的线性地址与KERNBASE \~ KERNBASE+4MB的线性地址获得相同的映射即可都映射到 0\~4MB的物理地址空间具体实现在pmm.c中pmm\_init函数的语句
```
```c
boot_pgdir[0] = boot_pgdir[PDX(KERNBASE)];
```
实际上这种映射也限制了内核的大小。当内核大小超过预期的3MB
@ -98,7 +98,7 @@ boot_pgdir[0] = boot_pgdir[PDX(KERNBASE)];
当执行完毕gdt\_init函数后新的段页式映射已经建立好了上面的0\~4MB的线性地址与0\~4MB的物理地址一一映射关系已经没有用了。
所以可以通过如下语句解除这个老的映射关系。
```
```c
boot_pgdir[0] = 0;
```
在page\_init函数建立完实现物理内存一一映射和页目录表自映射的页目录表和页表后一旦使能分页机制则ucore看到的内核虚拟地址空间如下图所示

View File

@ -52,7 +52,7 @@ SECTIONS {
virt addr - 0xC0000000 = linear addr = phy addr # 物理地址在0~4MB之内的三者映射关系
```
请注意`pmm_init`函数中的一条语句:
```
```c
boot_pgdir[0] = boot_pgdir[PDX(KERNBASE)];
```
就是用来建立物理地址在0~4MB之内的三个地址间的临时映射关系`virt addr - 0xC0000000 = linear addr = phy addr`。

View File

@ -32,14 +32,14 @@ boot\_pgdir[PDX(VPT)] = PADDR(boot\_pgdir) | PTE\_P | PTE\_W;
这些变量和语句有何特殊含义呢其实vpd变量的值就是页目录表的起始虚地址0xFAFEB000且它的高10位和中10位是相等的都是10进制的1003。当执行了上述语句就确保了vpd变量的值就是页目录表的起始虚地址且vpt是页目录表中第一个目录表项指向的页表的起始虚地址。此时描述内核虚拟空间的页目录表的虚地址为0xFAFEB000大小为4KB。页表的理论连续虚拟地址空间0xFAC00000\~0xFB000000大小为4MB。因为这个连续地址空间的大小为4MB可有1M个PTE即可映射4GB的地址空间。
但ucore实际上不会用完这么多项在memlayout.h中定义了常量
```
```c
#define KERNBASE 0xC0000000
#define KMEMSIZE 0x38000000 // the maximum amount of physical memory
#define KERNTOP (KERNBASE + KMEMSIZE)
```
表示ucore只支持896MB的物理内存空间这个896MB只是一个设定可以根据情况改变。则最大的内核虚地址为常量
```
```c
#define KERNTOP (KERNBASE + KMEMSIZE)=0xF8000000
```

View File

@ -1,11 +1,11 @@
**实现物理内存探测**
物理内存探测是在bootasm.S中实现的相关代码很短如下所示
```asm
```x86asm
probe_memory:
//对0x8000处的32位单元清零,即给位于0x8000处的
//struct e820map的成员变量nr_map清零
movl $0, 0x8000
movl $0, 0x8000
xorl %ebx, %ebx
//表示设置调用INT 15h BIOS中断后BIOS返回的映射地址描述符的起始地址
movw $0x8004, %di

View File

@ -6,7 +6,7 @@ ucore
kernel各个部分由组成kernel的各个.o或.a文件构成且各个部分在内存中地址位置由ld工具根据kernel.ld链接脚本linker
script来设定。ld工具使用命令-T指定链接脚本。链接脚本主要用于规定如何把输入文件各个.o或.a文件内的section放入输出文件lab2/bin/kernel即ELF格式的ucore内核
并控制输出文件内各部分在程序地址空间内的布局。下面简单分析一下/lab2/tools/kernel.ld来了解一下ucore内核的地址布局情况。kernel.ld的内容如下所示
```asm
```
/* Simple linker script for the ucore kernel.
See the GNU ld 'info' manual ("info ld") to learn the syntax. */
@ -122,7 +122,7 @@ segment指用来存放程序执行代码的一块内存区域。这部分
extern char edata[], end[];
```
但搜寻所有源码文件\*.[ch]没有发现有这两个变量的定义。那这两个变量从哪里来的呢其实在lab2/tools/kernel.ld中可以看到如下内容
```asm
```
.text : {
*(.text .stub .text.* .gnu.linkonce.t.*)