arm linux多核同时获取读写锁, 会死循环吗, 还是都得到写锁 2017-01-18
文来自本人的旧博客: http://blog.163.com/awaken_ing/blog/static/120613197201631133058159
本篇只提问, 不解答, 祝开心.
如果读写锁是unlocked, 然后cpu 0和cpu 1都想获取写锁, 如表格所示, CPU 0在t2时刻执行的是wfene, 这时, CPU 1执行的是ldrex, 然后是否会有cpu能够获取到锁? 源码来自 linux-3.10.86/arch/arm/include/asm/spinlock.h archwritelock()
时间 | CPU0 | 时间 | CPU1 |
---|---|---|---|
t0/t6 | 1: ldrex %0, [%1] | ||
t1/t7 | teq %0, #0 | ||
t2 | WFE("ne") | t2 | 1: ldrex %0, [%1] |
t3 | strexeq %0, %2, [%1] | t3 | teq %0, #0 |
t4 | teq %0, #0 | t4 | WFE("ne") |
t5 | bne 1b | t5 | strexeq %0, %2, [%1] |
t6 | t6 | teq %0, #0 | |
t7 | t7 | bne 1b |
qemu观察arm linux启动过程02 2017-01-18
文来自本人的旧博客 http://blog.163.com/awaken_ing/blog/static/12061319720157119242210
1. _createpage_tables
pgtbl r4 @ page table address
其中pgtbl为宏
.macro pgtbl, rd
ldr \rd, =(KERNEL_RAM_PADDR - 0x4000)
.endm
这里KERNELRAMPADDR和zreladdr的值相等.
1.1 identity mapping
/*
* Create identity mapping for first MB of kernel to
* cater for the MMU enable. This identity mapping
* will be removed by paging_init(). We use our current program
* counter to determine corresponding section base address.
*/
mov r6, pc
mov r6, r6, lsr #20 @ start of kernel section
orr r3, r7, r6, lsl #20 @ flags + kernel base
str r3, [r4, r6, lsl #2] @ identity mapping
@ 和arch\arm\boot\compressed\head.S类似
@ r3内容:
@ 31 20 19 0
@ PC高12bit __cpu_mm_mmu_flags
@存放的地址:
@ 31 14 13 2 1 0
@ 页表基址(0x4000) 页表index(pc高12bit) 00
qemu观察arm linux启动过程01 2017-01-18
文来自本人的旧博客 http://blog.163.com/awaken_ing/blog/static/12061319720157611510386
1. 方法
qemu-system-arm -M versatilepb -m 128M -kernel /opt/qemu_arm/linux-2.6.35.7/arch/arm/boot/compressed/vmlinux -S -s
需要留意, 这里-kernel的参数不是/opt/qemu_arm/linux-2.6.35.7/vmlinux
arm-none-linux-gnueabi-gdb -tui -q /opt/qemu_arm/linux-2.6.35.7/arch/arm/boot/compressed/vmlinux
Reading symbols from /opt/qemu_arm/linux-2.6.35.7/arch/arm/boot/compressed/vmlinux...done.
(gdb) target extended-remote localhost:1234
Remote debugging using localhost:1234
warning: Source file is more recent than executable.
start () at arch/arm/boot/compressed/head.S:115
(gdb) b __setup_mmu
Breakpoint 1 at 0x200: file arch/arm/boot/compressed/head.S, line 409.
(gdb) c
Continuing.
Breakpoint 1, __setup_mmu () at arch/arm/boot/compressed/head.S:409
(gdb) i r r3 r4
r3 0x4000 16384
r4 0x8000 32768
从create_mapping()看arm linux的页表 2017-01-18
来自本人的旧博客 http://blog.163.com/awaken_ing/blog/static/120613197201571932454226
createmapping会调用到allocinitpte(), 进而调用setpte_ext()
#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext)
这里qemu模拟的versatilepb ARM Versatile/PB (ARM926EJ-S) ARMv5TEJ
所以setpteext(pte, pfnpte(pfn, _pgprot(type->prot_pte)), 0);
就是
cpuarm926setpteext (pte, pfnpte(pfn, _pgprot(type->prot_pte)), 0);
/*
* cpu_arm926_set_pte_ext(ptep, pte, ext)
*
* Set a PTE and flush it out
*/
.align 5
ENTRY(cpu_arm926_set_pte_ext)
#ifdef CONFIG_MMU
armv3_set_pte_ext
mov r0, r0
#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
mcr p15, 0, r0, c7, c10, 1 @ clean D entry
#endif
mcr p15, 0, r0, c7, c10, 4 @ drain WB
#endif
mov pc, lr
arm linux的ASID (Address Space ID) 2017-01-18
来自本人的旧博客 http://blog.163.com/awaken_ing/blog/static/1206131972015112011286335
平台:ARM Versatile Express for Cortex-A9 (ARMv7)
# CONFIGARMLPAE is not set, 也就是使用Short-descriptor格式, ASID存储在CONTEXTIDR的低8 bit:
31 7 0
+-------------------------+-----------+
| PROCID | ASID |
+-------------------------+-----------+
页表项中 nG == 1时, 这个页表项信息就是 non-global, 或者说 process-specific, 对应的TLB中就会有ASID信息, 执行虚拟地址到物理地址转换时, ASID也需要参与该过程.
用户地址空间的页表才会设置nG标志 (内核地址的一部分地址范围使用TLB lockdown比较合适): linux-3.10.86/arch/arm/include/asm/pgtable.h
static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pteval)
{
...
if (addr < TASK_SIZE && pte_present_user(pteval)) {
...
ext |= PTE_EXT_NG;
}
...
set_pte_ext(ptep, pteval, ext);
}
set_pte_at -> set_pte_ext -> cpu_v7_set_pte_ext