/** @brief The driver need a physical space to run, we allocate and map it to its space */ static void allocate_physical_bulk(unsigned long *start, unsigned long *size, unsigned long map_base) { struct ke_mem_cluster_info info; /* Allocate physical for driver system */ if (NULL == km_cluster_alloc(&info, -1, false)) goto err; else { *start = info.page_start; *size = info.page_count * PAGE_SIZE; } /* Map to the virtual address space of driver system to access */ if (NULL == km_map_physical(info.page_start, *size, (map_base + info.page_start) | KM_MAP_PHYSICAL_FLAG_WITH_VIRTUAL | KM_MAP_PHYSICAL_FLAG_NORMAL_CACHE)) { goto err1; } return; err1: km_cluster_dealloc_base(info.page_start, true); err: *start = 0; *size = 0; }
/** @brief Map driver framework to kernel */ void ke_startup_driver_process(void *physical_data, size_t size) { unsigned long entry_address; unsigned long base; Elf32_Ehdr *hdr = (Elf32_Ehdr*)physical_data; if (hdr->e_ident[EI_CLASS] == ELFCLASS32) { entry_address = hdr->e_entry; } else if (hdr->e_ident[EI_CLASS] == ELFCLASS64) { Elf64_Ehdr *hdr64 = (Elf64_Ehdr*)physical_data; entry_address = hdr64->e_entry; } else { printk("不识别的驱动文件格式.\n"); goto end; } /* 64kb offset is not base */ base = entry_address & (~0xffff); // TODO: size of the map should contain bss, and notify system that bss should not be allocated for normal use */ /* Map physical to base */ if (km_map_physical(HAL_GET_BASIC_PHYADDRESS(physical_data), size + 0x60000/*BSS?*/, base | KM_MAP_PHYSICAL_FLAG_WITH_VIRTUAL | KM_MAP_PHYSICAL_FLAG_NORMAL_CACHE) == NULL) goto err; ((void(*)())entry_address)(&ddk); end: return; err: printk("驱动包影射到内核空间失败,可能是地址冲突,要影射的地址范围为%d@%x.\n", size, base); }
static void *mem_ioremap(unsigned long phy, unsigned long size, unsigned long flags) { /* Note: flags are flags in the name of this system */ return km_map_physical(phy, size, flags); }