//****************************************************** *//* 2007.6.18//****************************************************** *在/kernel/include/asm-arm/arch-s3c2410/bitfield.h 文件中:#ifndef __ASSEMBLY__#define UData(Data) ((unsigned long) (Data))#else#define UData(Data) (Data)#endif例:UData(5); = 5/** MACRO: Fld** Purpose* The macro "Fld" encodes a bit field, given its size and its shift value* with respect to bit 0.** Note* A more intuitive way to encode bit fields would have been to use their* mask. However, extracting size and shift value information from a bit* field''''s mask is cumbersome and might break the assembler (255-character* line-size limit).** Input* Size Size of the bit field, in number of bits.* Shft Shift value of the bit field with respect to bit 0.** Output* Fld Encoded bit field.*/#define Fld(Size, Shft) (((Size) << 16) + (Shft))例:Fld(2,5); = 0x20005/** MACROS: FSize, FShft, FMsk, FAlnMsk, F1stBit** Purpose* The macros "FSize", "FShft", "FMsk", "FAlnMsk", and "F1stBit" return* the size, shift value, mask, aligned mask, and first bit of a* bit field.** Input* Field Encoded bit field (using the macro "Fld").** Output* FSize Size of the bit field, in number of bits.* FShft Shift value of the bit field with respectto bit 0.* FMsk Mask for the bit field.* FAlnMsk Mask for the bit field, aligned on bit 0.* F1stBit First bit of the bit field.*/#define FSize(Field) ((Field) >> 16)例:FSize(0x20005); = 2#define FShft(Field) ((Field) & 0x0000FFFF)例:FShft(0x20005); = 5/** MACRO: FInsrt** Purpose* The macro "FInsrt" inserts a value into a bit field by shifting the* former appropriately.** Input* Value Bit-field value.* Field Encoded bit field (using the macro "Fld").** Output* FInsrt Bit-field value positioned appropriately.*/#define FInsrt(Value, Field) \(UData (Value) << FShft (Field))例:FInsrt(0x3, 0x20005); = 0x3 << 0x0005 = 0x60------------------------------------------------------------------------在/kernel/include/asm-arm/arch-s3c2410/hardware.h 文件中:/** S3C2410 internal I/O mappings** We have the following mapping:* phys virt* 48000000 e8000000*/#define VIO_BASE 0xe8000000 /* virtual start of IO space */#define PIO_START 0x48000000 /* physical start of IO space */#define io_p2v(x) ((x) | 0xa0000000)#define io_v2p(x) ((x) & ~0xa0000000)# define __REG(x) io_p2v(x)# define __PREG(x) io_v2p(x)这里,在实际的寄存器操作中,都用__REG(x) 宏将物理地址转换为了虚拟地址,然后再对这些虚拟地址进行读写操作。
------------------------------------------------------------------------当应用程序对设备文件进行ioctl操作时候会调用它们。
对于fb_get_fix(),应用程序传入的是fb_fix_screeninfo结构,在函数中对其成员变量赋值,主要是smem_start(缓冲区起始地址)和smem_len(缓冲区长度),最终返回给应用程序。
在/kernel/drivers/video/s3c2410fb.c 文件中的s3c2410fb_map_video_memory 函数中:fbi->fb.fix.smem_len = fbi->max_xres * fbi->max_yres * fbi->max_bpp / 8;fbi->map_size = PAGE_ALIGN(fbi->fb.fix.smem_len + PAGE_SIZE);fbi->map_cpu = consistent_alloc(GFP_KERNEL,fbi->map_size,&fbi->map_dma);if (fbi->map_cpu){fbi->screen_cpu = fbi->map_cpu + PAGE_SIZE;fbi->screen_dma = fbi->map_dma + PAGE_SIZE;fbi->fb.fix.smem_start = fbi->screen_dma;}在/kernel/include/asm-arm/proc-armo/page.h 文件中:/* PAGE_SHIFT determines the page size. This is configurable. */#if defined(CONFIG_PAGESIZE_16)#define PAGE_SHIFT 14 /* 16K */#else /* default */#define PAGE_SHIFT 15 /* 32K */#endif在/kernel/include/asm-arm/page.h 文件中:#define PAGE_SIZE (1UL << PAGE_SHIFT)#define PAGE_MASK (~(PAGE_SIZE-1))/* to align the pointer to the (next) page boundary */#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)在/kernel/arch/arm/mm/consistent.c 文件中:/** This allocates one page of cache-coherent memory space and returns* both the virtual and a "dma" address to that space. It is not clear* whether this could be called from an interrupt context or not. For* now, we expressly forbid it, especially as some of the stuff we do* here is not interrupt context safe.** Note that this does *not* zero the allocated area!*/void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)这里首先计算出需要视频缓冲区的大小(LCD屏的宽度 * LCD 屏的高度 * 每像素的位数 / 每字节的位数)fbi->fb.fix.smem_len = 240*320*16/8 = 0x25800 =150K(9.375个PAGE)PAGE_SHIFT = 14PAGE_SIZE = 1<<14 = 0x4000 = 16K (1个PAGE)PAGE_MASK = 0xFFFFC000fbi->map_size = PAGE_ALIGN(fbi->fb.fix.smem_len +PAGE_SIZE) = PAGE_ALIGN(150K + 16K) = PAGE_ALIGN(166K) = (166K + 16K - 1) & 0xFFFFC000 = 0x2D7FF & 0xFFFFC000 = 0x2C000 =176Kconsistent_alloc(GFP_KERNEL, 176K, &fbi->map_dma);最后得到:framebuffer(物理地址)|---------------|| ... |-------|---------------| <-- fbi->map_dma| 16K |分配了 |---------------| <-- fbi->screen_dma =fbi->fb.fix.smem_start176K | |共11个 | | 160K = 10个PAGEPAGE | 160K | 可以容下所需的150K 视频缓冲区大小 (16K) | || |-------|---------------|-------| ... ||---------------|//****************************************************** *//* 2007.6.19//****************************************************** *在/kernel/drivers/video/s3c2410fb.c 文件中的s3c2410fb_activate_var 函数中:unsigned long VideoPhysicalTemp = fbi->screen_dma;这里已经得到了framebuffer 在内存中的起始地址为VideoPhysicalTemp,地址数据位为A[30:0]。