《设备树 — 引入设备树,内核文件的位置变化(八)》

  针对重复的代码问题,如果不同的SOC使用了相同的IP block(例如I2C controller),那么这个driver的code要从各个arch/arm/mach-xxx中独立出来,变成一个通用的模块供各个SOC specific的模块使用。移动到哪个目录呢?对于I2C或者USB OTG而言,这些HW block的驱动当然应该移动到kernel/drivers目录。因为,对于这些外设,可能是in-chip,也可能是off-chip的,但是对于软件而言,它们是没有差别的(或者说好的软件抽象应该掩盖底层硬件的不同)。对于那些system level的code呢?例如clock control、interrupt control。其实这些也不是ARM-specific,应该属于linux kernel的核心代码,应该放到linux/kernel目录下,属于core-Linux-kernel frameworks。当然对于ARM平台,也需要保存一些和framework交互的code,这些code叫做ARM SoC core architecture code。OK,总结一下:

1、ARM的核心代码仍然保存在arch/arm目录下

2、ARM SoC core architecture code保存在arch/arm目录下

3、ARM SOC的周边外设模块的驱动保存在drivers目录下

4、ARM SOC的特定代码在arch/arm/mach-xxx目录下

5、ARM SOC board specific的代码被移除,由Device Tree机制来负责传递硬件拓扑和硬件资源信息。 

  本质上,Device Tree改变了原来用hardcode方式将HW 配置信息嵌入到内核代码的方法,改用bootloader传递一个DB的形式。对于基于ARM CPU的嵌入式系统,我们习惯于针对每一个platform进行内核的编译。但是随着ARM在消费类电子上的广泛应用(甚至桌面系统、服务器系统),我们期望ARM能够象X86那样用一个kernel image来支持多个platform。在这种情况下,如果我们认为kernel是一个black box,那么其输入参数应该包括:
  

1、识别platform的信息
2、runtime的配置参数
3、设备的拓扑结构以及特性

  对于嵌入式系统,在系统启动阶段,bootloader会加载内核并将控制权转交给内核,此外,还需要把上述的三个参数信息传递给kernel,以便kernel可以有较大的灵活性。在linux kernel中,Device Tree的设计目标就是如此。

  

  针对重复的代码问题,如果不同的SOC使用了相同的IP block(例如I2C controller),这些都会集中统一管理,放在driver/目录下。 

  就比如说S5PV210的Display controller和Exynos 4412的Display controller使用的是同一个IP block,那么关于这个IP block,的通用的代码应该是统一组织放在driver/目录下,他们两个IP block,针对不同的SOC,不同的可能是这个控制器在SOC的起始地址可能不同,当然这个就比较好解决了,这个也是Device tree应该且必要做的事情。
  例如在s5pv210中,起始地址是从0xf8000000开始的

  

   而exyson-4412中,起始地址则是在0x11c00000

  

   这样如果一个芯片厂家如果使用相同IP block的Display controller,将来就可以不用写相关的驱动了,而只需要在设备树文件中描述自己SOC中对这个IP block的寄存器地址,时钟,中断信息的就可以了。

  当然,对于像USB中的ohci,ehci或者xhci更是如此,毕竟这些控制器,都是USB协议规定的,一般来说基本上大多数厂家寄存器的排布地址都会是一样的。

  所以对于SOC厂家,都只需要在设备树中指定寄存器起始地址,中断,时钟信息等就可以了,完全不用自己在向之前一样要根据一块单板或一款SOC就要写一个控制器写一个类似的驱动程序。

原文地址:https://www.cnblogs.com/zhuangquan/p/12882062.html