static int open_mapping_f(int cap) { int mapsize, estsize, padsize; if (cap) Q_printf("MAPPING: open, cap=%s\n", decode_mapping_cap(cap)); padsize = 4*1024; /* first estimate the needed size of the mapfile */ mapsize = HMASIZE >> 10; /* HMA */ /* VGAEMU */ mapsize += config.vgaemu_memsize ? config.vgaemu_memsize : 1024; mapsize += config.ems_size; /* EMS */ mapsize += LOWMEM_SIZE >> 10; /* Low Mem */ estsize = mapsize; /* keep heap fragmentation in mind */ mapsize += (mapsize/4 < padsize ? padsize : mapsize/4); mpool_numpages = mapsize / 4; mapsize = mpool_numpages * PAGE_SIZE; /* make sure we are page aligned */ ftruncate(tmpfile_fd, 0); if (ftruncate(tmpfile_fd, mapsize) == -1) { if (!cap) error("MAPPING: cannot size temp file pool, %s\n",strerror(errno)); discardtempfile(); if (!cap)return 0; leavedos(2); } /* /dev/shm may be mounted noexec, and then mounting PROT_EXEC fails. However mprotect may work around this (maybe not in future kernels) */ mpool = mmap(0, mapsize, PROT_READ|PROT_WRITE, MAP_SHARED, tmpfile_fd, 0); if (mpool == MAP_FAILED || mprotect(mpool, mapsize, PROT_READ|PROT_WRITE|PROT_EXEC) == -1) { char *err = strerror(errno); char s[] = "MAPPING: cannot size temp file pool, %s\n"; discardtempfile(); if (!cap) { Q_printf(s,err); return 0; } leavedos(2); } /* the memory pool itself can just be rw though */ mprotect(mpool, mapsize, PROT_READ|PROT_WRITE); Q_printf("MAPPING: open, mpool (min %dK) is %d Kbytes at %p-%p\n", estsize, mapsize/1024, mpool, mpool+mapsize-1); sminit(&pgmpool, mpool, mapsize); /* * Now handle individual cases. * Don't forget that each of the below code pieces should only * be executed once ! */ #if 0 if (cap & MAPPING_OTHER) { /* none for now */ } #endif #if 0 if (cap & MAPPING_EMS) { /* none for now */ } #endif #if 0 if (cap & MAPPING_DPMI) { /* none for now */ } #endif #if 0 if (cap & MAPPING_VIDEO) { /* none for now */ } #endif #if 0 if (cap & MAPPING_VGAEMU) { /* none for now */ } #endif #if 0 if (cap & MAPPING_HGC) { /* none for now */ } #endif #if 0 if (cap & MAPPING_HMA) { /* none for now */ } #endif #if 0 if (cap & MAPPING_SHARED) { /* none for now */ } #endif #if 0 if (cap & MAPPING_INIT_HWRAM) { /* none for now */ } #endif #if 0 if (cap & MAPPING_INIT_LOWRAM) { /* none for now */ } #endif return 1; }
static int open_mapping_shm(int cap) { static int first =1; if (cap) Q_printf("MAPPING: open, cap=%s\n", decode_mapping_cap(cap)); if (first) { void *ptr1, *ptr2 = MAP_FAILED; first = 0; /* do a test alias mapping. kernel 2.6.1 doesn't support our mremap trick */ ptr1 = mmap(0, PAGE_SIZE, PROT_NONE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); if (ptr1 != MAP_FAILED) { ptr2 = mremap(ptr1, 0, PAGE_SIZE, MREMAP_MAYMOVE); munmap(ptr1, PAGE_SIZE); if (ptr2 != MAP_FAILED) munmap(ptr2, PAGE_SIZE); } if (ptr2 == MAP_FAILED) { Q_printf("MAPPING: not using mapshm because alias mapping does not work\n"); if (!cap)return 0; leavedos(2); } } /* * Now handle individual cases. * Don't forget that each of the below code pieces should only * be executed once ! */ #if 0 if (cap & MAPPING_OTHER) { /* none for now */ } #endif #if 0 if (cap & MAPPING_EMS) { /* none for now */ } #endif #if 0 if (cap & MAPPING_DPMI) { /* none for now */ } #endif #if 0 if (cap & MAPPING_VIDEO) { /* none for now */ } #endif #if 0 if (cap & MAPPING_VGAEMU) { /* none for now */ } #endif #if 0 if (cap & MAPPING_HGC) { /* none for now */ } #endif #if 0 if (cap & MAPPING_HMA) { /* none for now */ } #endif #if 0 if (cap & MAPPING_SHARED) { /* none for now */ } #endif #if 0 if (cap & MAPPING_INIT_HWRAM) { /* none for now */ } #endif #if 0 if (cap & MAPPING_INIT_LOWRAM) { /* none for now */ } #endif return 1; }
static void close_mapping_file(int cap) { Q_printf("MAPPING: close, cap=%s\n", decode_mapping_cap(cap)); if (cap == MAPPING_ALL && tmpfile_fd != -1) discardtempfile(); }
static void close_mapping_shm(int cap) { Q_printf("MAPPING: close, cap=%s\n", decode_mapping_cap(cap)); }