ARM linux电源管理——Cortex A系列CPU(32位)睡眠和唤醒的底层汇编实现
承接 http://www.wowotech.net/pm_subsystem/suspend_and_resume.html
Linux电源管理(6)_Generic PM之Suspend功能一文中的下图。
本文主要分析平台相关的CPU睡眠和唤醒,即下电和上电流程,以及ARM底层汇编代码实现。
内核版本:3.1.0 CPU:ARM Cortex-A7
1 平台相关函数执行流程
上图最后调入suspend_ops->enter,这是个平台相关的函数。
平台相关的cpu suspend_enter函数:
如果有中断挂起,则直接返回;
读取设备的idle状态;
设置CPU0的热跳转寄存器,睡眠唤醒后,跳转到这个地址
允许cpu0睡眠
不屏蔽SCU断电、自断电功能
不屏蔽CPU自断电功能,当CPU进入WFI状态,CPU 自动断电
改变CPU的频率、电压输出
调用cpu_suspend函数
恢复CPU的频率、电压输出
屏蔽自断电功能
屏蔽SCU断电、自断电功能
不允许CPU0睡眠
cpu_suspend函数调用流程图
2 睡眠过程详细分析
cpu_suspend: (arch/arm/kernel/suspend.c)
int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
函数携带两个参数,第二个参数是函数指针(参数是unsigned long型的,返回值是int型的),第一个参数就是前面的函数指针被调用时需要的参数,故为unsigned long型的
if (!idmap_pgd) //非常有意思的一个变量,稍后再解释
return -EINVAL;
调用 __cpu_suspend
__cpu_suspend:(arch/arm/kernel/sleep.S)
携带的参数就是调用cpu_suspend函数时传入的参数。
R0(unsigned long arg,实际上是个地址,地址存放的类型是suspend_args,是个参数,供R1函数调用时使用)
R1(睡眠函数,执行时需要的参数就是R0)
#define cpu_suspend_size __glue(CPU_NAME,_suspend_size) arch/arm/include/asm/glue-proc.h
#define __glue(name,fn) ____glue(name,fn) arch/arm/include/asm/glue.h
#define ____glue(name,fn) name##fn
define CPU_NAME cpu_v7
.equ cpu_v7_suspend_size, 4 * 8(arch/arm/mm/proc.v7.S)
故 cpu_suspend_size == cpu_v7_suspend_size
入栈R4-R11,LR
没有定义MULTI_CPU,R4赋值cpu_suspend_size,为32
R5就是入栈后堆栈的地址,图中的1处
R4加上12
然后将堆栈地址减去(32+12),就是让开11个寄存器的值,图中的3处
入栈R0,R1
R0赋值堆栈地址加上8,图中的3处
R1赋值R4,就是44
R2赋值R5,就是图中的1处
R3赋值临时栈地址,文件下面定义了数个(看内核配置了多少个CPU来定)unsigned long 型的地址空间
定义了多核,根据CPU的ID,获取当前CPU的临时栈地址
跳转到__cpu_suspend_save
__cpu_suspend_save:(arch/arm/kernel/suspend.c)
R3即当前CPU的临时栈地址,存入R0的值(物理的地址),图中的3处
以R0为基地址,入栈idmap_pgd的物理地址、入栈当前的堆栈(图中的1处,是个虚拟地址)、入栈唤醒函数( cpu_do_resume 的物理地址)
cpu_do_suspend(glue-proc.h),-> cpu_v7_do_suspend (arch/arm/mm/proc.v7.S)携带的参数R0就是刚入完3个寄存器后的堆栈地址
入栈R4-R10,LR;
以传入的参数R0为栈基地址,入栈R4、R5(PID、线程ID)
入栈R6-R11(域ID,页表基地址寄存器1、页表控制寄存器、系统控制寄存器、辅助寄存器、协处理器访问控制寄存器),加上上面的2个正好是8个;
弹出R4-R10,PC;
刷新cache、二级cache,保证数据确实写到了内存,栈空间也是内存的一部分
LR赋值cpu_suspend_abort
弹出r0,PC ,就是跳转到上面的fn函数指针处
若这个fn函数执行过程中返回了,则调转到lr处,就是cpu_suspend_abort
cpu_suspend_abort:
此时的SP就是图中的3处,弹出到R1,R2,R3。
判断R0的值,若不是0,则将其赋值1
堆栈SP赋值R2的值,图中的1处
堆栈弹出R4-R11,PC。实际是返回到cpu_suspend函数中,调用__cpu_suspend函数的地方。
fn函数执行过程,若最终执行成功,则执行wfi指令,CPU顺利下电
清除Icache,刷dcache。
关闭SMP位
关闭对应的CCI端口
然后进入WFI睡眠,低功耗状态
如果中间出现了差错,则直接返回1后,接着下面的cpu_suspend_abort执行,仍然能够返回到cpu_suspend函数,其中__cpu_suspend函数的返回值强行变为了1
3 唤醒过程详细分析
低功耗模式被唤醒后,跳转到唤醒地址
设置SVC模式,关闭IRQ、FIQ
使能对应的CCI端口
清除SMP位,清除跳转预测等,开启I cache
跳转到cpu_resume的物理地址
cpu_resume:
获取当前CPU的临时栈地址,保存到R0中,图中的3处
设置SVC模式,关闭I、F
以R0为基地址,弹出R1、SP、PC,R1就是 idmap_pgd
跳转到cpu_do_resume,就是cpu_v7_do_resume
cpu_v7_do_resume
清除TLB、I cache、上下文ID
再次以R0为基地址,弹出R4-R5,并恢复PID、线程ID,
弹出R6-R11,
恢复域ID
将R1的内容设置到页表基地址寄存器0,为开启MMU做准备
恢复页表基地址寄存器1,页表控制寄存器
恢复辅助寄存器,协处理器访问控制寄存器
设置内存属性间接寄存器
将系统控制寄存器R8内容赋值与R0,跳转到cpu_resume_mmu
cpu_resume_mmu:
将R0设置系统控制器寄存器,开启MMU后,跳转到下面的虚拟地址,cpu_resume_after_mmu
cpu_resume_after_mmu:
cpu_init 执行CPU的初始化
R0赋值为0,
此时的SP是虚拟的,然后弹出R4-R11,PC。接着返回到cpu_suspend函数,__cpu_suspend函数的返回值是0
cpu_switch_mm(mm->pgd, mm);
cpu_v7_switch_mm: proc-v7-2level.S
设置context ID
设置TTB,页表转换基地址 将基地址由idmap_pgd变为mm->pgd
4、idmap_pgd变量
pgd_t *idmap_pgd;
typedef pmdval_t pgd_t[2];
typedef u32 pmdval_t;
故 pgd_t是一个无符号32位的数组, idmap_pgd 是个指针,指向有两个变量的的数组,变量类型是无符号32位的数
init_static_idmap函数
idmap_pgd = pgd_alloc(&init_mm);赋值重新分配后的一个内存地址,4K的大小,且里面已经填充了很多东西了
idmap_start获取__idmap_text_start对应的物理地址
immap_end获取__idmap_text_end对应的物理地址
identity_mapping_add(idmap_pgd, idmap_start, idmap_end); 建立1:1的隐射,从idmap_start开始到idmap_end结束
从我编译的内核来看,是下面的这4段代码,都是跟开启、关闭MMU相关的。
c055dcb8 T __idmap_text_start
c055dcb8 T __kprobes_text_end
c055dcb8 T __kprobes_text_start
c055dcb8 T __turn_mmu_on head.s 开启MMU
c055dcd8 t __turn_mmu_on_end
c055dcd8 T cpu_resume_mmu sleep.s 有开启MMU的过程
c055dcfc T cpu_v7_reset proc-v7.s 关闭MMU
c055dd40 T comip_mmu_off sleep.s
c055dd80 T __idmap_text_end
idmap_pgd指向内存中的4K大小的一段空间,实际是页表基地址c000 4000对应的物理地址开始的一个备份(部分的是一样的),而且还将开启、关闭MMU的代码都1:1映射了。这样在cpu_switch_mm之前,就可以启用MMU了,有页表基地址idmap_pgd,且建立了隐射。
其实CPU0在从uboot跳转到压缩内核处,解压缩完毕,跳转到arch/arm/kernel/head.s 。
__create_page_tables时,也曾经为__turn_mmu_on到__turn_mmu_on_end这一段,建立了1:1的隐射
在init_static_idmap函数的结尾打印c000 4000开始的页表地址内容,备份的页表地址idmap_pgd的内容,如下所示,只打印不是0的内容。
c000 4000开始的内容如下:
0xc0006ff0 : 00000000 00000000 1effc811 1effcc11
0xc0007000 : 0641140e 0651140e 0661140e 0671140e
0xc0007010 : 0681140e 0691140e 06a1140e 06b1140e
0xc0007020 : 06c1140e 06d1140e 06e1140e 06f1140e
0xc0007030 : 0701140e 0711140e 0721140e 0731140e
0xc0007040 : 0741140e 0751140e 0761140e 0771140e
0xc0007050 : 0781140e 0791140e 07a1140e 07b1140e
0xc0007060 : 07c1140e 07d1140e 07e1140e 07f1140e
0xc0007070 : 0801140e 0811140e 0821140e 0831140e
0xc0007080 : 0841140e 0851140e 0861140e 0871140e
0xc0007090 : 0881140e 0891140e 08a1140e 08b1140e
0xc00070a0 : 08c1140e 08d1140e 08e1140e 08f1140e
0xc00070b0 : 0901140e 0911140e 0921140e 0931140e
0xc00070c0 : 0941140e 0951140e 0961140e 0971140e
0xc00070d0 : 0981140e 0991140e 09a1140e 09b1140e
0xc00070e0 : 09c1140e 09d1140e 09e1140e 09f1140e
0xc00070f0 : 0a01140e 0a11140e 0a21140e 0a31140e
0xc0007100 : 0a41140e 0a51140e 0a61140e 0a71140e
0xc0007110 : 0a81140e 0a91140e 0aa1140e 0ab1140e
0xc0007120 : 0ac1140e 0ad1140e 0ae1140e 0af1140e
0xc0007130 : 0b01140e 0b11140e 0b21140e 0b31140e
0xc0007140 : 0b41140e 0b51140e 0b61140e 0b71140e
0xc0007150 : 0b81140e 0b91140e 0ba1140e 0bb1140e
0xc0007160 : 0bc1140e 0bd1140e 0be1140e 0bf1140e
0xc0007170 : 0c01140e 0c11140e 0c21140e 0c31140e
0xc0007180 : 0c41140e 0c51140e 0c61140e 0c71140e
0xc0007190 : 0c81140e 0c91140e 0ca1140e 0cb1140e
0xc00071a0 : 0cc1140e 0cd1140e 0ce1140e 0cf1140e
0xc00071b0 : 0d01140e 0d11140e 0d21140e 0d31140e
0xc00071c0 : 0d41140e 0d51140e 0d61140e 0d71140e
0xc00071d0 : 0d81140e 0d91140e 0da1140e 0db1140e
0xc00071e0 : 0dc1140e 0dd1140e 0de1140e 0df1140e
0xc00071f0 : 0e01140e 0e11140e 0e21140e 0e31140e
0xc0007200 : 0e41140e 0e51140e 0e61140e 0e71140e
0xc0007210 : 0e81140e 0e91140e 0ea1140e 0eb1140e
0xc0007220 : 0ec1140e 0ed1140e 0ee1140e 0ef1140e
0xc0007230 : 0f01140e 0f11140e 0f21140e 0f31140e
0xc0007240 : 0f41140e 0f51140e 0f61140e 0f71140e
0xc0007250 : 0f81140e 0f91140e 0fa1140e 0fb1140e
0xc0007260 : 0fc1140e 0fd1140e 0fe1140e 0ff1140e
0xc0007270 : 1001140e 1011140e 1021140e 1031140e
0xc0007280 : 1041140e 1051140e 1061140e 1071140e
0xc0007290 : 1081140e 1091140e 10a1140e 10b1140e
0xc00072a0 : 10c1140e 10d1140e 10e1140e 10f1140e
0xc00072b0 : 1101140e 1111140e 1121140e 1131140e
0xc00072c0 : 1141140e 1151140e 1161140e 1171140e
0xc00072d0 : 1181140e 1191140e 11a1140e 11b1140e
0xc00072e0 : 11c1140e 11d1140e 11e1140e 11f1140e
0xc00072f0 : 1201140e 1211140e 1221140e 1231140e
0xc0007300 : 1241140e 1251140e 1261140e 1271140e
0xc0007310 : 1281140e 1291140e 12a1140e 12b1140e
0xc0007320 : 12c1140e 12d1140e 12e1140e 12f1140e
0xc0007330 : 1301140e 1311140e 1321140e 1331140e
0xc0007340 : 1341140e 1351140e 1361140e 1371140e
0xc0007350 : 1381140e 1391140e 13a1140e 13b1140e
0xc0007360 : 13c1140e 13d1140e 13e1140e 13f1140e
0xc0007370 : 1401140e 1411140e 1421140e 1431140e
0xc0007380 : 1441140e 1451140e 1461140e 1471140e
0xc0007390 : 1481140e 1491140e 14a1140e 14b1140e
0xc00073a0 : 14c1140e 14d1140e 14e1140e 14f1140e
0xc00073b0 : 1501140e 1511140e 1521140e 1531140e
0xc00073c0 : 1541140e 1551140e 1561140e 1571140e
0xc00073d0 : 1581140e 1591140e 15a1140e 15b1140e
0xc00073e0 : 15c1140e 15d1140e 15e1140e 15f1140e
0xc00073f0 : 1601140e 1611140e 1621140e 1631140e
0xc0007400 : 1641140e 1651140e 1661140e 1671140e
0xc0007410 : 1681140e 1691140e 16a1140e 16b1140e
0xc0007420 : 16c1140e 16d1140e 16e1140e 16f1140e
0xc0007430 : 1701140e 1711140e 1721140e 1731140e
0xc0007440 : 1741140e 1751140e 1761140e 1771140e
0xc0007450 : 1781140e 1791140e 17a1140e 17b1140e
0xc0007460 : 17c1140e 17d1140e 17e1140e 17f1140e
0xc0007470 : 1801140e 1811140e 1821140e 1831140e
0xc0007480 : 1841140e 1851140e 1861140e 1871140e
0xc0007490 : 1881140e 1891140e 18a1140e 18b1140e
0xc00074a0 : 18c1140e 18d1140e 18e1140e 18f1140e
0xc00074b0 : 1901140e 1911140e 1921140e 1931140e
0xc00074c0 : 1941140e 1951140e 1961140e 1971140e
0xc00074d0 : 1981140e 1991140e 19a1140e 19b1140e
0xc00074e0 : 19c1140e 19d1140e 19e1140e 19f1140e
0xc00074f0 : 1a01140e 1a11140e 1a21140e 1a31140e
0xc0007500 : 1a41140e 1a51140e 1a61140e 1a71140e
0xc0007510 : 1a81140e 1a91140e 1aa1140e 1ab1140e
0xc0007520 : 1ac1140e 1ad1140e 1ae1140e 1af1140e
0xc0007530 : 1b01140e 1b11140e 1b21140e 1b31140e
0xc0007540 : 1b41140e 1b51140e 1b61140e 1b71140e
0xc0007550 : 1b81140e 1b91140e 1ba1140e 1bb1140e
0xc0007560 : 1bc1140e 1bd1140e 1be1140e 1bf1140e
0xc0007570 : 1c01140e 1c11140e 1c21140e 1c31140e
0xc0007580 : 1c41140e 1c51140e 1c61140e 1c71140e
0xc0007590 : 1c81140e 1c91140e 1ca1140e 1cb1140e
0xc00075a0 : 1cc1140e 1cd1140e 1ce1140e 1cf1140e
0xc00075b0 : 1d01140e 1d11140e 1d21140e 1d31140e
0xc00075c0 : 1d41140e 1d51140e 1d61140e 1d71140e
0xc00075d0 : 1d81140e 1d91140e 1da1140e 1db1140e
0xc00075e0 : 1dc1140e 1dd1140e 1de1140e 1df1140e
0xc00075f0 : 1e01140e 1e11140e 1e21140e 1e31140e
0xc0007600 : 1e41140e 1e51140e 1e61140e 1e71140e
0xc0007610 : 1e81140e 1e91140e 1ea1140e 1eb1140e
0xc0007620 : 1ec1140e 1ed1140e 1ee1140e 1ef1140e
0xc0007640 : 1e023811 1e023c11 00000000 00000000
0xc0007e00 : a0011452 a0111452 a0211452 a0311452
0xc0007e10 : a0411452 a0511452 a0611452 a0711452
0xc0007e20 : a0811452 a0911452 a0a11452 00000000
0xc0007f40 : e1011452 e1111452 00000000 00000000
0xc0007ff0 : 00000000 00000000 1effe821 1effec21
idmap_pgd开始的内容如下:
0xd7c681a0 : 06800402 06900402 00000000 00000000
0xd7c6aff0 : 00000000 00000000 1effc811 1effcc11
0xd7c6b000 : 0641140e 0651140e 0661140e 0671140e
0xd7c6b010 : 0681140e 0691140e 06a1140e 06b1140e
0xd7c6b020 : 06c1140e 06d1140e 06e1140e 06f1140e
0xd7c6b030 : 0701140e 0711140e 0721140e 0731140e
0xd7c6b040 : 0741140e 0751140e 0761140e 0771140e
0xd7c6b050 : 0781140e 0791140e 07a1140e 07b1140e
0xd7c6b060 : 07c1140e 07d1140e 07e1140e 07f1140e
0xd7c6b070 : 0801140e 0811140e 0821140e 0831140e
0xd7c6b080 : 0841140e 0851140e 0861140e 0871140e
0xd7c6b090 : 0881140e 0891140e 08a1140e 08b1140e
0xd7c6b0a0 : 08c1140e 08d1140e 08e1140e 08f1140e
0xd7c6b0b0 : 0901140e 0911140e 0921140e 0931140e
0xd7c6b0c0 : 0941140e 0951140e 0961140e 0971140e
0xd7c6b0d0 : 0981140e 0991140e 09a1140e 09b1140e
0xd7c6b0e0 : 09c1140e 09d1140e 09e1140e 09f1140e
0xd7c6b0f0 : 0a01140e 0a11140e 0a21140e 0a31140e
0xd7c6b100 : 0a41140e 0a51140e 0a61140e 0a71140e
0xd7c6b110 : 0a81140e 0a91140e 0aa1140e 0ab1140e
0xd7c6b120 : 0ac1140e 0ad1140e 0ae1140e 0af1140e
0xd7c6b130 : 0b01140e 0b11140e 0b21140e 0b31140e
0xd7c6b140 : 0b41140e 0b51140e 0b61140e 0b71140e
0xd7c6b150 : 0b81140e 0b91140e 0ba1140e 0bb1140e
0xd7c6b160 : 0bc1140e 0bd1140e 0be1140e 0bf1140e
0xd7c6b170 : 0c01140e 0c11140e 0c21140e 0c31140e
0xd7c6b180 : 0c41140e 0c51140e 0c61140e 0c71140e
0xd7c6b190 : 0c81140e 0c91140e 0ca1140e 0cb1140e
0xd7c6b1a0 : 0cc1140e 0cd1140e 0ce1140e 0cf1140e
0xd7c6b1b0 : 0d01140e 0d11140e 0d21140e 0d31140e
0xd7c6b1c0 : 0d41140e 0d51140e 0d61140e 0d71140e
0xd7c6b1d0 : 0d81140e 0d91140e 0da1140e 0db1140e
0xd7c6b1e0 : 0dc1140e 0dd1140e 0de1140e 0df1140e
0xd7c6b1f0 : 0e01140e 0e11140e 0e21140e 0e31140e
0xd7c6b200 : 0e41140e 0e51140e 0e61140e 0e71140e
0xd7c6b210 : 0e81140e 0e91140e 0ea1140e 0eb1140e
0xd7c6b220 : 0ec1140e 0ed1140e 0ee1140e 0ef1140e
0xd7c6b230 : 0f01140e 0f11140e 0f21140e 0f31140e
0xd7c6b240 : 0f41140e 0f51140e 0f61140e 0f71140e
0xd7c6b250 : 0f81140e 0f91140e 0fa1140e 0fb1140e
0xd7c6b260 : 0fc1140e 0fd1140e 0fe1140e 0ff1140e
0xd7c6b270 : 1001140e 1011140e 1021140e 1031140e
0xd7c6b280 : 1041140e 1051140e 1061140e 1071140e
0xd7c6b290 : 1081140e 1091140e 10a1140e 10b1140e
0xd7c6b2a0 : 10c1140e 10d1140e 10e1140e 10f1140e
0xd7c6b2b0 : 1101140e 1111140e 1121140e 1131140e
0xd7c6b2c0 : 1141140e 1151140e 1161140e 1171140e
0xd7c6b2d0 : 1181140e 1191140e 11a1140e 11b1140e
0xd7c6b2e0 : 11c1140e 11d1140e 11e1140e 11f1140e
0xd7c6b2f0 : 1201140e 1211140e 1221140e 1231140e
0xd7c6b300 : 1241140e 1251140e 1261140e 1271140e
0xd7c6b310 : 1281140e 1291140e 12a1140e 12b1140e
0xd7c6b320 : 12c1140e 12d1140e 12e1140e 12f1140e
0xd7c6b330 : 1301140e 1311140e 1321140e 1331140e
0xd7c6b340 : 1341140e 1351140e 1361140e 1371140e
0xd7c6b350 : 1381140e 1391140e 13a1140e 13b1140e
0xd7c6b360 : 13c1140e 13d1140e 13e1140e 13f1140e
0xd7c6b370 : 1401140e 1411140e 1421140e 1431140e
0xd7c6b380 : 1441140e 1451140e 1461140e 1471140e
0xd7c6b390 : 1481140e 1491140e 14a1140e 14b1140e
0xd7c6b3a0 : 14c1140e 14d1140e 14e1140e 14f1140e
0xd7c6b3b0 : 1501140e 1511140e 1521140e 1531140e
0xd7c6b3c0 : 1541140e 1551140e 1561140e 1571140e
0xd7c6b3d0 : 1581140e 1591140e 15a1140e 15b1140e
0xd7c6b3e0 : 15c1140e 15d1140e 15e1140e 15f1140e
0xd7c6b3f0 : 1601140e 1611140e 1621140e 1631140e
0xd7c6b400 : 1641140e 1651140e 1661140e 1671140e
0xd7c6b410 : 1681140e 1691140e 16a1140e 16b1140e
0xd7c6b420 : 16c1140e 16d1140e 16e1140e 16f1140e
0xd7c6b430 : 1701140e 1711140e 1721140e 1731140e
0xd7c6b440 : 1741140e 1751140e 1761140e 1771140e
0xd7c6b450 : 1781140e 1791140e 17a1140e 17b1140e
0xd7c6b460 : 17c1140e 17d1140e 17e1140e 17f1140e
0xd7c6b470 : 1801140e 1811140e 1821140e 1831140e
0xd7c6b480 : 1841140e 1851140e 1861140e 1871140e
0xd7c6b490 : 1881140e 1891140e 18a1140e 18b1140e
0xd7c6b4a0 : 18c1140e 18d1140e 18e1140e 18f1140e
0xd7c6b4b0 : 1901140e 1911140e 1921140e 1931140e
0xd7c6b4c0 : 1941140e 1951140e 1961140e 1971140e
0xd7c6b4d0 : 1981140e 1991140e 19a1140e 19b1140e
0xd7c6b4e0 : 19c1140e 19d1140e 19e1140e 19f1140e
0xd7c6b4f0 : 1a01140e 1a11140e 1a21140e 1a31140e
0xd7c6b500 : 1a41140e 1a51140e 1a61140e 1a71140e
0xd7c6b510 : 1a81140e 1a91140e 1aa1140e 1ab1140e
0xd7c6b520 : 1ac1140e 1ad1140e 1ae1140e 1af1140e
0xd7c6b530 : 1b01140e 1b11140e 1b21140e 1b31140e
0xd7c6b540 : 1b41140e 1b51140e 1b61140e 1b71140e
0xd7c6b550 : 1b81140e 1b91140e 1ba1140e 1bb1140e
0xd7c6b560 : 1bc1140e 1bd1140e 1be1140e 1bf1140e
0xd7c6b570 : 1c01140e 1c11140e 1c21140e 1c31140e
0xd7c6b580 : 1c41140e 1c51140e 1c61140e 1c71140e
0xd7c6b590 : 1c81140e 1c91140e 1ca1140e 1cb1140e
0xd7c6b5a0 : 1cc1140e 1cd1140e 1ce1140e 1cf1140e
0xd7c6b5b0 : 1d01140e 1d11140e 1d21140e 1d31140e
0xd7c6b5c0 : 1d41140e 1d51140e 1d61140e 1d71140e
0xd7c6b5d0 : 1d81140e 1d91140e 1da1140e 1db1140e
0xd7c6b5e0 : 1dc1140e 1dd1140e 1de1140e 1df1140e
0xd7c6b5f0 : 1e01140e 1e11140e 1e21140e 1e31140e
0xd7c6b600 : 1e41140e 1e51140e 1e61140e 1e71140e
0xd7c6b610 : 1e81140e 1e91140e 1ea1140e 1eb1140e
0xd7c6b620 : 1ec1140e 1ed1140e 1ee1140e 1ef1140e
0xd7c6b640 : 1e023811 1e023c11 00000000 00000000
0xd7c6be00 : a0011452 a0111452 a0211452 a0311452
0xd7c6be10 : a0411452 a0511452 a0611452 a0711452
0xd7c6be20 : a0811452 a0911452 a0a11452 00000000
0xd7c6bf40 : e1011452 e1111452 00000000 00000000
0xd7c6bff0 : 00000000 00000000 1effe821 1effec21
可以看出,两者的内容除了0xd7c681a0处,两个隐射不一样外,其它内容都是相同的。
而0xd7c681a0处,减去0xd7c68000,算出来对应的虚拟地址是0680 0000开始的2M内容,而此处实际的物理地址填充的是06800402 06900402,则真好是1:1的段隐射。
在cpu_suspend函数时,先判断idmap_pgd是否为空,若不为空,则CPU在上电完成后开启MMU时,用到的页表基地址就是idmap_pgd。后面判断ret是否为0,若为0,则CPU经历了下电又上电,需要替换页表基地址。
其实多核CPU的启动,其它CPU启动,开启MMU时,用到的页表基地址也是idmap_pgd,跳转到C语言的secondary_start_kernel函数后,执行cpu_switch_mm(mm->pgd, mm),这个也是为了替换页表基地址。