关于arm linux的map_io 2017-01-18

文来自本人的旧博客 http://blog.163.com/awaken_ing/blog/static/1206131972016226674429

1. 主要流程

平台:versatilepb ARM Versatile/PB (ARM926EJ-S) 内核版本2.6.35.7

paging_init
|--devicemaps_init
|   |--from VMALLOC_END, pmd_clear(pmd_off_k(addr))
|   |--mdesc->map_io() => versatile_map_io  
|   |   |--iotable_init
|   |   |   |--create_mapping

2. 为何是 MT_DEVICE

linux-2.6.35.7/arch/arm/mach-versatile/core.c

void __init versatile_map_io(void)
{
    iotable_init(versatile_io_desc, ARRAY_SIZE(versatile_io_desc));
}

static struct map_desc versatile_io_desc[] __initdata = {
    {
        ...
        .type       = MT_DEVICE
    },
    ...

中断, softirq, tasklet的区别 2017-01-18

1. 中断流程

假定 CONFIGMULTIIRQHANDLER=y, handlearchirq 为 gichandle_irq.
linux-3.10.86/arch/arm/kernel/setup.c

__irq_svc @entry-armv.S
|   |--svc_entry    保存spsr_<exception> 到r5
|   |--irq_handler
|   |   |--handle_arch_irq => gic_handle_irq
|   |   |   |--irq_find_mapping  完成 an hw irq number到a linux irq的转换
|   |   |   |--handle_IRQ(irqnr, regs) if not IPI 
|   |   |   |       |--generic_handle_irq  -> generic_handle_irq_desc -> handle_fasteoi_irq
|   |   |   |       |   |--raw_spin_lock(&desc->lock);
|   |   |   |       |   |--handle_irq_event
|   |   |   |       |   |   |--raw_spin_unlock(&desc->lock);
|   |   |   |       |   |   |--handle_irq_event_percpu -> action->handler
|   |   |   |       |   |   |--raw_spin_lock(&desc->lock);
|   |   |   |       |   |--chip->irq_eoi
|   |   |   |       |   |--raw_spin_unlock(&desc->lock);
|   |   |   |       |--irq_exit();  这里中断还是禁用的吗? 答:是的, ifndef __ARCH_IRQ_EXIT_IRQS_DISABLED
|   |   |   |       |   |--WARN_ON_ONCE(!irqs_disabled());
|   |   |   |       |   |--if( ... ) invoke_softirq() 
|   |   |   |       |   |    |--do_softirq -> __do_softirq
|   |   |   |       |   |    |    |--local_irq_enable   //修改CPSR I bit, 打开中断
|   |   |   |       |   |    |    |--h->action(h)
|   |   |   |       |   |    |    |--local_irq_disable  //这里为何又禁止中断???
|   |   |   |       |--set_irq_regs(old_regs)  这里开启中断? 答:不是.
|   |--svc_exit r5, irq = 1  @entry-header.S

arm linux的iounmap()如何处理主页表(master page table)的同步 2017-01-18

来自本人的旧博客: http://blog.163.com/awaken_ing/blog/static/120613197201510308269773

1. 背景

平台为qemu ARM Versatile/PB (ARM926EJ-S) ARMv5TEJ, UP

我们知道进程的内核地址空间的页表 和 swapperpgdir 进行同步, 在进程创建时, do_fork()会拷贝一级页表.

2. 问题

vmalloc() area发生异常, 由dotranslationfault()处理, 处理的是一级页表无效的情况, 处理方法: If the init_task's first level page tables contains the relevant entry, we copy the it to this task.

可以猜想, vmalloc区域的页表是 两级页表(低两位D1D0为0b01), 而不是section (D1D0为0b10)

打印vmalloc区域的对应的页表, 可以看到 D1D0 既有0b01(指向二级页表), 也有0b10(无需二级页表) 的.

从cat /proc/vmallocinfo可知, 可知0b10不是由vmalloc()引发的页表创建, 而是ioremap(). (这里并不是说ioremap创建的都是section)

虚拟地址0xc9000000开始对应的一级页表entry

arm linux中断处理过程中寄存器的保存 2017-01-18

来自本人的旧博客 http://blog.163.com/awaken_ing/blog/static/1206131972015839465987

模式   usr            exception                                   svc                             
-----|----|--------------------------------|---------------------------------------------------                                                                                               
函数                 vector_\name:                             usr_entry:                         


                                                                            对应的汇编语句:                    
                  +----------------+        0  +------------------+   ------------------------    
           高地址 |spsr_<exception>|           |      r0          |      str     r1, [sp]         
                  |                |        4  +------------------+    ----------------------     
             ^    +----------------+           |      r1          |                               
             |    |                |           |                  |                               
             |    |lr_<exception>  |           |      .           |                               
             |    |                |           |      .           |      stmib   sp, {r1 - r12}   
             |    +----------------+           |      .           |                               
                  |                |           |                  |                               
           低地址 |      r0        |           |     r12          |                               
                  |                |           |                  |                               
                  +----------------+       52  +------------------+     ----------------------    
                    struct stack               |      sp_usr      |                               
                                               |                  |                               
                                           56  +------------------+     stmdb   r0, {sp, lr}^     
                                               |     lr_usr       |                               
                                               |                  |                               
                                           60  +------------------+      ---------------------    
                                               |  lr_<exception>  |                               
                                               |                  |                               
                                           64  +------------------+                                
                                               | spsr_<exception> |      stmia   r0, {r2 - r4}    
                                               |                  |                               
                                           68  +------------------+                               
                                               |      -1          |                               
                                               |                  |                               
                                           72  +------------------+     -----------------------   
                                                struct  pt_regs

SLUB 04:tid 2017-01-14

1. tid

linux-3.10.86/include/linux/slub_def.h

struct kmem_cache_cpu {
    ...
    unsigned long tid;  /* Globally unique transaction id */
    ..
};

linux-3.10.86/mm/slub.c

#ifdef CONFIG_PREEMPT
/*
 * Calculate the next globally unique transaction for disambiguiation
 * during cmpxchg. The transactions start with the cpu number and are then
 * incremented by CONFIG_NR_CPUS.

问题:一次不是加1, 而是加CONFIGNRCPUS, 为啥?
答:这个设计是为了让任何时刻每个cpu的tid值都不一样. 不过上面的注释有点老, 因为实际并不是加CONFIGNRCPUS, 而是TID_STEP.