setup_paging(head.s)

setup_paging(head.s)

Content #

//代码路径:boot/head.s

.align 2
setup_paging:
    movl   $1024*5,%ecx           /* 5 pages - pg_dir + 4 page tables */
    xorl   %eax,%eax
    xorl   %edi,%edi              /* pg_dir is at 0x000 */
    cld;rep;stosl
/*下面几行中的7应看成二进制的111,是页属性,代表u/s、r/w、present,
111代表:用户u、读写rw、存在p,000代表:内核s、只读r、不存在  */
    movl   $pg0 + 7,_pg_dir       /* set present bit/user r/w */
    movl   $pg1 + 7,_pg_dir + 4   /*  --------- " " --------- */
    movl   $pg2 + 7,_pg_dir + 8   /*  --------- " " --------- */
    movl   $pg3 + 7,_pg_dir + 12  /*  --------- " " --------- */
    movl   $pg3 + 4092,%edi
    movl   $0xfff007,%eax         /*  16Mb -4096 + 7 (r/w user,p) */
    std
1: stosl                          /* fill pages backwards-more efficient :-) */
    subl   $0x1000,%eax
    jge 1b
    

这些工作完成后,内存中的布局如 内存结构图(head.s执行后)所示。可以看出,只有184字节的剩余代码。

PG(Paging)标志:CR0寄存器的第31位,分页机制控制位。当CPU的控制寄存器 CR0第0位PE(保护模式)置为1时,可设置PG位为开启。当开启后,地址映射模式采取分页机制。当CPU的控制寄存器CR0第0位PE(保护模式)置为0时,设置PG 位将引起CPU发生异常。

CR3寄存器:3号32位控制寄存器,其高20位存放页目录表的基地址。当CR0中的 PG标志置位时,CPU使用CR3指向的页目录表和页表进行虚拟地址到物理地址的映射。

执行代码如下:

//代码路径:boot/head.s
    
    xorl   %eax,%eax              /* pg_dir is at 0x0000 */
    movl   %eax,%cr3              /* cr3-page directory start */
    movl   %cr0,%eax
    orl    $0x80000000,%eax
    movl   %eax,%cr0              /* set paging (PG) bit */
    

前两行代码的动作是将CR3指向页目录表,意味着操作系统认定0x0000这个位置就是页目录表的起始位置;后3行代码的动作是启动分页机制开关PG标志置位,以启用分页寻址模式。两个动作一气呵成。

From #

Linux内核设计的艺术

stos(Store String)