龙芯开源社区

 找回密码
 注册新用户(newuser)
查看: 8026|回复: 13

16k页大小,那么32位地址怎么划分呢?

[复制链接]
发表于 2007-5-24 09:15:43 | 显示全部楼层 |阅读模式
16k页大小,那么32位地址怎么划分呢?


pgd+pte+14=32

pgd=?   
pte=?

[ 本帖最后由 pwp 于 2007-5-25 09:49 AM 编辑 ]
 楼主| 发表于 2007-5-24 10:36:07 | 显示全部楼层
接着问  pgd_current里存放的是虚拟地址吧?  大于 0x80000000的
 楼主| 发表于 2007-5-24 11:26:18 | 显示全部楼层
再接着问   pgd  存放的是不是pte的虚拟地址? 我觉得存虚址就可以了,省得还要变换一次。
但是pte里必须存放page的物理地址了。
发表于 2007-5-24 12:41:01 | 显示全部楼层

回复 #1 pwp 的帖子

pgd只有一页,16k/4=4k个pte页,每个页4k项页表,32位时没有用满pgd

pgd_current和pgd项都是存虚地址

BTW:这个问题在开发者乐园更合适。
 楼主| 发表于 2007-5-25 10:53:42 | 显示全部楼层
呵呵下次一定注意。
但是第一个问题还没有明白。

我猜测pgd=10,因为PGDIR_SHIFT=22。
pte=8,对么?

另外,每个pgd项都是32位的,页大小是16k,那么是不是低14位做保护位?
pte也应该是低14位做保护位,是么?
谢谢

[ 本帖最后由 pwp 于 2007-5-25 11:06 AM 编辑 ]
 楼主| 发表于 2007-5-25 11:44:26 | 显示全部楼层
我写了个模块,想打印出当前pgd中的数据
unsigned long *pgd;
unsigned long *tmp1;

pgd=0x80488018;   //从System.map中看到 pgd_current的地址是这个
printk("pgd is %x *pgd is %x\n",pgd,*pgd);
for(i=0;i<4096;i++)    //每个pgd中可以有4k项
  {
         tmp1=pgd+4*i;
         if (i%100==0)
              printk("address is %x  data is %x  \n",tmp1,*tmp1);
  }
运行结果如下:
pgd is 80488018 *pgd is 86194000
address is 80488018  data is 86194000
address is 80488658  data is 1011a08
address is 80488c98  data is dc0cb0c
address is 804892d8  data is 450b040b
address is 80489918  data is 24b18
address is 80489f58  data is d0d8009
address is 8048a598  data is d180f040
address is 8048abd8  data is 604800f0
address is 8048b218  data is 20903030
address is 8048b858  data is b090b060
address is 8048be98  data is 11822110
address is 8048c4d8  data is 0
address is 8048cb18  data is 0
address is 8048d158  data is 0
address is 8048d798  data is 2b9c7408
address is 8048ddd8  data is 20
address is 8048e418  data is ffffffff
address is 8048ea58  data is 8e5a
address is 8048f098  data is 0
address is 8048f6d8  data is 2fc0f7a8
address is 8048fd18  data is 0
address is 80490358  data is 0
address is 80490998  data is 0
address is 80490fd8  data is 0
address is 80491618  data is 0
address is 80491c58  data is 0
address is 80492298  data is 0
address is 804928d8  data is 0
address is 80492f18  data is 0
address is 80493558  data is 0
address is 80493b98  data is 0
address is 804941d8  data is 0
address is 80494818  data is 7a5b
address is 80494e58  data is 0
address is 80495498  data is 0
address is 80495ad8  data is 0
address is 80496118  data is 7abb
address is 80496758  data is 0
address is 80496d98  data is 0
address is 804973d8  data is 0
address is 80497a18  data is 7b5d

我的问题是:既然pgd中填的都是虚拟地址,都应该大于0x80000000,为什么会有小于的??
发表于 2007-5-28 20:00:27 | 显示全部楼层
有吗?
发表于 2007-5-30 14:20:24 | 显示全部楼层
麻烦老大转到开发者乐园版,大家好好讨论后准备加精
发表于 2007-5-30 17:21:08 | 显示全部楼层
我做了一个模块把内核生成的tlbrefill程序拷贝了出来(64位内核),然后反汇编了一下,很容易从中看出pgd,pmd,pt这些table是怎么划分的,反汇编如下:

       0:    00403a40     dmfc0    k0,$8
       4:    17004007     bltz    k0,0x64
       8:    4e801b3c     lui    k1,0x804e
       c:    00407bdf     ld    k1,16384(k1)
/*加载的是pdg_current的地址*/
      10:    7ed01a00     dsrl32   k0,k0,0x1
      14:    f83f5a33     andi    k0,k0,0x3ff8

/*  pgd:addr[33:46],低三位没用
从内核代码中可以看出,所有的表都用的是14位地址(用的都是宏PAGE_SHIFT,16k页的话就是14位地址)作为索引的*/

      18:    2dd87a03     daddu    k1,k1,k0
      1c:    00403a40     dmfc0    k0,$8
      20:    00007bdf     ld    k1,0(k1)
      24:    bad51a00     dsrl    k0,k0,0x16
      28:    f83f5a33     andi    k0,k0,0x3ff8

/*PMD:addr[22:35],低三位没用*/

      2c:    2dd87a03     daddu    k1,k1,k0
      30:    00a03a40     dmfc0    k0,$20
      34:    00007bdf     ld    k1,0(k1)
      38:    bad01a00     dsrl    k0,k0,0x2
      3c:    f03f5a33     andi    k0,k0,0x3ff0
/*PT:addr[11:24],从Context里面取出BadVPN2来进行计算的
低4位没用,因此就是表项是[14:24]进行索引,刚好是16k的页表*/

      40:    2dd87a03     daddu    k1,k1,k0
      44:    00007adf     ld    k0,0(k1)
      48:    08007bdf     ld    k1,8(k1)
/*EntryLo0和EntryLo1都是8字节的*/
      4c:    bad11a00     dsrl    k0,k0,0x6
/*这个大概是内核的处理,写table的时候在低六位记录了什么信息*/
      50:    00109a40     mtc0    k0,$2
      54:    bad91b00     dsrl    k1,k1,0x6
      58:    00189b40     mtc0    k1,$3
      5c:    06000042     tlbwr
      60:    18000042     eret
      64:    b8d81a00     dsll    k1,k0,0x2
      68:    04006107     bgez    k1,0x7c
      6c:    00c01b3c     lui    k1,0xc000
      70:    2fd05b03     dsubu    k0,k0,k1
      74:    e6ff0010     b    0x10
      78:    4d801b3c     lui    k1,0x804d
      7c:    3cd81b00     dsll32    k1,k1,0x0
      80:    2fd05b03     dsubu    k0,k0,k1
      84:    e2ff0010     b    0x10
      88:    4e801b3c     lui    k1,0x804e



另外2e的tlb和xtlb都使用的是0地址的入口地址,而且处理是相同的
我自己有个疑问,不太明白蓝色部分是什么作用?


附件是读取程序的模块,modprobe main以后
cat /proc/read_ex_handler > a.bin
objdump -D -b binary -m mips a.bin 即可得到反汇编
32位内核可以也一样的做一下

[ 本帖最后由 kingkongmao 于 2007-5-30 06:40 PM 编辑 ]

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册新用户(newuser)

x
发表于 2007-5-30 17:22:33 | 显示全部楼层

回复 #9 kingkongmao 的帖子

m文件里面的内核代码路径需要按照各自情况修改一下

本版积分规则

小黑屋|手机版|Archiver|Lemote Inc.  

GMT+8, 2019-6-16 08:45 , Processed in 0.233109 second(s), 21 queries .

快速回复 返回顶部 返回列表