// Driver entry point. Initializes globals and registers driver node in /dev. kern_return_t pmem_start(kmod_info_t * ki, void *d) { int error = 0; pmem_log("Loading /dev/%s driver", pmem_pmem_devname); // Memory allocations are tagged to prevent leaks pmem_tag = OSMalloc_Tagalloc(pmem_tagname, OSMT_DEFAULT); // Allocate one page for zero padding of illegal read requests pmem_zero_page = static_cast<uint8_t *>(OSMalloc(PAGE_SIZE, pmem_tag)); if (pmem_zero_page == NULL) { pmem_error("Failed to allocate memory for page buffer"); return pmem_cleanup(KERN_FAILURE); } bzero(pmem_zero_page, PAGE_SIZE); // Access the boot arguments through the platform export, // and parse the systems physical memory configuration. boot_args * ba = reinterpret_cast<boot_args *>(PE_state.bootArgs); pmem_physmem_size = ba->PhysicalMemorySize; pmem_mmap = reinterpret_cast<EfiMemoryRange *>(ba->MemoryMap + pmem_kernel_voffset); pmem_mmap_desc_size = ba->MemoryMapDescriptorSize; pmem_mmap_size = ba->MemoryMapSize; pmem_log("Size of physical memory:%lld", pmem_physmem_size); pmem_log("Size of physical pages:%d (PAGE_SHIFT=%d, PAGE_MASK=%#016x)", PAGE_SIZE, PAGE_SHIFT, PAGE_MASK); pmem_log("Phys. Memory map at:%#016llx (size:%lld desc_size:%d)", pmem_mmap, pmem_mmap_size, pmem_mmap_desc_size); pmem_log("Number of segments in memory map: %d", pmem_mmap_size / pmem_mmap_desc_size); // Install switch table pmem_devmajor = cdevsw_add(-1, &pmem_cdevsw); if (pmem_devmajor == -1) { pmem_error("Failed to create character device"); return pmem_cleanup(KERN_FAILURE); } // Create physical memory device file pmem_log("Adding node /dev/%s", pmem_pmem_devname); pmem_devpmemnode = devfs_make_node(makedev(pmem_devmajor, pmem_dev_pmem_minor), DEVFS_CHAR, UID_ROOT, GID_WHEEL, 0660, pmem_pmem_devname); if (pmem_devpmemnode == NULL) { pmem_error("Failed to create /dev/%s node", pmem_pmem_devname); return pmem_cleanup(KERN_FAILURE); } pmem_log("obtaining kernel dtb pointer"); __asm__ __volatile__("movq %%cr3, %0" :"=r"(pmem_dtb)); // Only bits 51-12 (inclusive) in cr3 are part of the dtb pointer pmem_dtb &= ~PAGE_MASK; pmem_log("kernel dtb: %#016llx", pmem_dtb); pmem_log("initializing pte_mmap module"); pmem_log("pmem driver loaded, physical memory available in /dev/%s", pmem_pmem_devname); return error; }
// Driver entry point. Initializes globals and registers driver node in /dev. kern_return_t chipsec_start(kmod_info_t * ki, void *d) { int error = 0; pmem_log("Loading /dev/%s driver", chipsec_devname); // Memory allocations are tagged to prevent leaks pmem_tag = OSMalloc_Tagalloc(pmem_tagname, OSMT_DEFAULT); // Allocate one page for zero padding of illegal read requests pmem_zero_page = static_cast<uint8_t *>(OSMalloc(PAGE_SIZE, pmem_tag)); if (pmem_zero_page == NULL) { pmem_error("Failed to allocate memory for page buffer"); return pmem_cleanup(KERN_FAILURE); } bzero(pmem_zero_page, PAGE_SIZE); // Install the character device chipsec_dev_major = cdevsw_add(-1, &pmem_cdevsw); if (chipsec_dev_major == -1) { pmem_error("Failed to create character device"); return pmem_cleanup(KERN_FAILURE); } // Create physical memory device file pmem_log("Adding node /dev/%s", chipsec_devname); pmem_devpmemnode = devfs_make_node(makedev(chipsec_dev_major, chipsec_dev_minor), DEVFS_CHAR, UID_ROOT, GID_WHEEL, 0660, chipsec_devname); if (pmem_devpmemnode == NULL) { pmem_error("Failed to create /dev/%s node", chipsec_devname); return pmem_cleanup(KERN_FAILURE); } pmem_log("pmem driver loaded, physical memory available in /dev/%s", chipsec_devname); return error; }
// Driver cleanup function, frees all memory and removes device nodes. kern_return_t pmem_stop(kmod_info_t *ki, void *d) { pmem_log("Unloading /dev/%s driver", pmem_pmem_devname); return pmem_cleanup(KERN_SUCCESS); }