1. 程式人生 > >hisi mmz模組驅動講解

hisi mmz模組驅動講解

一、概述          如圖所示,在海思平臺上將記憶體分為兩個部分:os記憶體和mmz記憶體。os記憶體指:由linux作業系統管理的記憶體;mmz記憶體:由mmz驅動模組進行管理供媒體業務單獨使用的記憶體,在驅動載入時可以指定該模組管理記憶體的大小:

insmod mmz.ko mmz=anonymous,0,0x4fa00000,6Manony=1 || report_error

         該驅動主要由兩個檔案組成:media-mem.c和mmz-userdev.c,載入驅動後相應的裝置檔案:/dev/mmz_userdev,應用層通過開啟該裝置檔案進行ioctl(申請mmz記憶體、釋放mmz記憶體、重對映mmz記憶體到核心等)和直接mmap操作,而媒體底層驅動模組則直接呼叫mmz驅動的匯出介面進行相應操作。

二、資料結構 1、mmz區域描述符          hil_media_memory_zone描述了一個mmz區域的所有資訊,可以有多個mmz區域,通過連結串列連線在一起。

struct hil_media_memory_zone {

   char name[HIL_MMZ_NAME_LEN+1]; //mmz區域名字:anonymous

   unsigned long gfp;   //區域標識:0

   unsigned long phys_start; //mmz區域起始實體地址:0x4fa00000

   unsigned long nbytes; //mmz區域大小:6M

   struct list_head list; //mmz連結串列

   unsigned char *bitmap; //點陣圖

   struct list_head mmb_list; //mmz區域的mmb連結串列,存放所有申請到的實體記憶體

   unsigned int alloc_type;

   unsigned long block_align;

   void (*destructor)(const void *);

};

2、mmb記憶體描述符          hil_media_memory_block描述了從mmz區域申請一塊記憶體,同一個mmz區域內的所有mmb通過連結串列連線。

struct hil_media_memory_block {

   #ifndef MMZ_V2_SUPPORT

   unsigned int id;

   #endif

   char name[HIL_MMB_NAME_LEN+1]; //該mmb模組使用者名字

   struct hil_media_memory_zone *zone; //指向mmb所屬的mmz區域

   struct list_head list; //mmb連結串列

   unsigned long phys_addr; //申請到的mmb起始實體地址

   void *kvirt;  //對應核心虛擬地址,從程式碼看未用

   unsigned long length; //申請的mmb大小

   unsigned long flags; //標識

   unsigned int order;

   int phy_ref; //引用計數

   int map_ref; //引用計數

};

3、mmz_userdev_info

         該結構體儲存開啟該裝置檔案的程序資訊,存放在file結構體的private_data成員裡。

struct mmz_userdev_info {

   pid_t pid;         //開啟裝置檔案的程序pid

   pid_t mmap_pid;

   struct semaphore sem; //訊號量

   struct list_head list; //指向mmb_info連結串列

};

4、mmb_info

         該結構體描述應用申請到mmb後的相關資訊,同進程的mmb_info通過連結串列形式管理。

struct mmb_info {

   unsigned long phys_addr;    //申請到的實體記憶體,同mmb.phys.addr

   unsigned long align;        /* ifyou need your phys-memory have special align size */

   unsigned long size;     //申請的實體記憶體大小

   unsigned int order;

    void *mapped;       //指向mmap後的虛擬地址空間

   union {

       struct {

           unsigned long prot  :8; /*PROT_READ or PROT_WRITE */

           unsigned long flags :12;/* MAP_SHARED or MAP_PRIVATE */

#ifdef __KERNEL__

           unsigned long reserved :8; /* reserved, do not use */

           unsigned long delayed_free :1;

           unsigned long map_cached :1;

#endif

       };

       unsigned long w32_stuf;

   };

   char mmb_name[HIL_MMB_NAME_LEN+1];

   char mmz_name[HIL_MMZ_NAME_LEN+1];

   unsigned long gfp;      /*reserved, do set to 0 */

#ifdef __KERNEL__

   int map_ref;

   int mmb_ref;

   struct list_head list;    //mmb_info連結串列

   hil_mmb_t *mmb;     //指向申請到的mmb

#endif

};

三、關係圖 1、mmz和mmb關係          下圖展示了mmz驅動管理mmz和mmb的關係。mmz驅動模組支援多個mmz區域,只要在載入mmz.ko時通過引數傳遞即可,一般情況下只有一個mmz區域。多個mmz區域之間通過連結串列的形式組織在一起,連結串列頭為mmz_list;而每個mmz區域通過mmb_list維護mmb連結串列,管理該區域內所有已經申請了的實體記憶體區域;每個mmb通過zone成員知道自己屬於哪個mmz區域。

         通過/proc/media-mem可以檢視mmz和mmb使用情況:

+---ZONE: PHYS(0x4FA00000, 0x4FFFFFFF),GFP=0, nBYTES=6144KB,  NAME="anonymous"

  |-MMB: phys(0x4FA00000, 0x4FA81FFF), kvirt=0x  (null), flags=0x00000000, length=520KB,       name="DCCM_MSG_BUF"

  |-MMB: phys(0x4FA82000, 0x4FA84FFF), kvirt=0x  (null), flags=0x00000000, length=12KB,        name="SYS_scale_coef"

  |-MMB: phys(0x4FA85000, 0x4FA87FFF), kvirt=0x  (null), flags=0x00000000, length=12KB,        name="SYS_scale_coef"

  |-MMB: phys(0x4FA88000, 0x4FB07FFF), kvirt=0x  (null), flags=0x00000000, length=512KB,       name="TDE_MemPool"

   |-MMB: phys(0x4FB08000, 0x4FB3CFFF),kvirt=0x  (null), flags=0x00000000,length=212KB,      name="IVE_QUEUE"

  |-MMB: phys(0x4FB3D000, 0x4FB3DFFF), kvirt=0x  (null), flags=0x00000000, length=4KB,name="IVE_TEMP_NODE"

---MMZ_USE_INFO:

 total size=6144KB(6MB),used=1272KB(1MB +248KB),remain=4872KB(4MB + 776KB),zone_number=1,block_number=6

2、mmb、mmb_info和mmb_userdev_info關係          下圖展示了mmz驅動和應用申請資料結構之間的關係:

         當應用開啟裝置檔案/dev/mmz_userdev時會申請一個屬於該程序的mmb_userdev_info結構體,mmb_userdev_info成員list指向屬於該程序的所有mmb_info,mmb_info的mmb成員指向為其分配的mmb,而*mmaped存放mmb實體記憶體(phy_addr)進行對映後的虛擬地址供使用者空間使用。