????DMA????
????DMA?????????CPU??μ?????????????????????????????????????????????????????У?????????????????????а?????????????????????????????????????CPU????????????????????
????DMA??cache???????
????cache????CPU?????????棬????CPU???ζ?????????????????潻??????????????????????????????DMA???????????????????????????????????????????CPU?????
????“?????豸??????????Щ?????????滺?????У????????????????豸????DMA???????????????????DMA??????Щ????RAM??浥?????????????????????е?????????д??RAM?У????????豸?????????????滺?????е?????”
???????????????????????DMA????????
?????????DMA???
?????????????????????????κζ?DMA?????????д?????????μ?????У??????“?????”????“??μ?”??
???????DMA???
?????????????????????????????????????????????????DMA???????????
?????????????DMA????????????2???(??DMA????????????????S3C2410??????????):
????1. ????DMA????????
??????DMA?豸??????S/G?????/?????????????£???????????????????????????linux?????????????????????????????棺kmalloc()??__get_free_pages()???????????????з???????????????kmalloc???????????λ??????64KB??__get_free_pages()?????????λ?????????2^order????????order??????????include/linux/Mmzone.h????е?MAX_ORDER?????????????2.6.18???汾?У??ú????10??????????????__get_free_pages??????ζ???????1<<10 * 4KB???4MB????????????棬??Xilinx Zynq Linux????У??ú????11????
????2. ??????????
???????DMA???????ж?д??????????????DMA?豸????????????dma_map_single()???????????DMA?????????????????????????????????????????????????????????
????3. ?????????
??????DMA???????????????????????????????dma_unmap_single()??????
???????
????(1). ???????????????????????????????????RAM???豸??DMA???????????????б??????????dma_sync_single_for_device()?????????DMA??????????????????С?
????(2). ???豸??RAM?????DMA?????????????豸????????????????????滺?????????????б??????????????????????????????????dma_sync_single_for_cpu()????????????????????????Ч??
????(3). ???kmalloc????????__get_free_pages?????????kmalloc??????????????????kfree????__get_free_pages??????????????????free_pages????????__get_free_pages?й??????????????????????£?
????????????
????alloc_pages(gfp_mask??order)
???????????????????????????????????????????????????NULL??
????__get_free_pages(gfp_mask??order)
??????????alloc_pages()??????????????????????????????????????????????????????????????????virt_to_page(addr)?????????????
????????????
????__free_pages(page??order)
??????????????page??????????????????????????????
????free_pages(page??order)
?????????????????__free_pages(page??order)????????????????????????????????????addr
????DMA??????????????
????1??DMA???????????????????
????typedef struct dma_buf_s {
????int size;    /* buffer size???????С */
????dma_addr_t dma_start;    /* starting DMA address ?????????????????*/
????int ref;    /* number of DMA references ???????????????*/
????void *id;    /* to identify buffer from outside ??? */
????int write;    /* 1: buf to write ?? 0: buf to read DMA??????д*/
????struct dma_buf_s *next;    /* next buf to process ????????????????*/
????} dma_buf_t;
????2??DMA????????????
????/* DMA control register structure */
????typedef struct {
????volatile u_long DISRC;/?????????
????volatile u_long DISRCC;//?????????
????volatile u_long DIDST;//???????
????volatile u_long DIDSTC;//??????????
????volatile u_long DCON;//DMA????????
????volatile u_long DSTAT;//???????
????volatile u_long DCSRC;//????
????volatile u_long DCDST;//??????
????volatile u_long DMASKTRIG;//????????????
????} dma_regs_t;
????3??DMA?豸?????
????/* DMA device structre */
????typedef struct {
????dma_callback_t callback;//DMA????????????????????ж?????????е???
????u_long dst;//???????????
????u_long src;//??????????
????u_long ctl;//???豸?????????????
????u_long dst_ctl;//??????????????
????u_long src_ctl;//?????????????
????} dma_device_t;