至于怎样处理的,跟计算机平台,使用的总线以及页表有关,很复杂的。
看下LDD3下面的I/O操作内容吧。
对于48000000--5b00001c的那些特殊寄存器,在访问前应先按照cpu说明书上的地址在linux中申请同样的地址空间,成为io内存,再去访问----------因为
寄存器的地址对cpu而言是不变、既定的,但linux并不知道这些,比如他不知道WTCON寄存器的地址是0x53000000,所以要访问硬件WTCON的时候驱动程序必须先向linux申请从0x53000000开始的一段地址,用的便是request_mem_region(res->start, size, pdev->name),然后再将申请到的地址控件用ioremap转化成虚拟地址再去访问........当然如果你访问WTCON的时候却向内核申请了比如0x54000000(在0x54000000还未被申请的情况下,应该可以申请成功),这样访问到的寄存器便不是WTCON了
request_mem_region仅仅是linux对IO内存的管理,意思指这块内存我已经占用了,别人就不要动了,也不能被swap出去。使用这些寄存器时,可以不调用request_mem_region,但这样的话就不能阻止别人对他的访问了
后来看了一下request_mem_region源码,里面有个死循环在保护已被申请过的资源不被其他代码再request_mem_region成功。
在__request_region里面会再次分配一个struct resource *res,内核使用write_lock使这个res被独占的写,但是内核并没有保护那个驱动中可以接触的比如上面的static struct resource s3c_wdt_resource,所以
如果第二个驱动不去request_mem_region还是可以访问第一个驱动中request_mem_region过的资源的,但这样就可能两者都访问到不正确的结果。所以在每个驱动模块在使用io内存之前最好都要先使request_mem_region申请一下,这样就利用到了内核提供的锁保护机制,不用在自己的驱动中再写代码去防止已经申请到的资源被其他驱动有意无意的伤害到。目前的理解。