void HMA_MAP(int HMA) { int ret; /* destroy simx86 memory protections first */ e_invalidate_full(HMAAREA, HMASIZE); /* Note: MAPPING_HMA is magic, dont be confused by src==dst==HMAAREA here */ off_t src = HMA ? HMAAREA : 0; x_printf("Entering HMA_MAP with HMA=%d\n", HMA); ret = alias_mapping(MAPPING_HMA, HMAAREA, HMASIZE, PROT_READ | PROT_WRITE | PROT_EXEC, LOWMEM(src)); if (ret == -1) { x_printf("HMA: Mapping HMA to HMAAREA %#x unsuccessful: %s\n", HMAAREA, strerror(errno)); leavedos(47); } x_printf("HMA: mapped\n"); }
/* * DANG_BEGIN_FUNCTION low_mem_init * * description: * Initializes the lower 1Meg via mmap & sets up the HMA region * * DANG_END_FUNCTION */ void low_mem_init(void) { void *lowmem, *result; #ifdef __i386__ PRIV_SAVE_AREA #endif open_mapping(MAPPING_INIT_LOWRAM); g_printf ("DOS+HMA memory area being mapped in\n"); lowmem = alloc_mapping(MAPPING_INIT_LOWRAM, LOWMEM_SIZE + HMASIZE, -1); if (lowmem == MAP_FAILED) { perror("LOWRAM alloc"); leavedos(98); } #ifdef __i386__ /* we may need root to mmap address 0 */ enter_priv_on(); result = alias_mapping(MAPPING_INIT_LOWRAM, 0, LOWMEM_SIZE + HMASIZE, PROT_READ | PROT_WRITE | PROT_EXEC, lowmem); leave_priv_setting(); if (result == MAP_FAILED && (errno == EPERM || errno == EACCES)) { #ifndef X86_EMULATOR perror ("LOWRAM mmap"); fprintf(stderr, "Cannot map low DOS memory (the first 640k).\n" "You can most likely avoid this problem by running\n" "sysctl -w vm.mmap_min_addr=0\n" "as root, or by changing the vm.mmap_min_addr setting in\n" "/etc/sysctl.conf or a file in /etc/sysctl.d/ to 0.\n" "If this doesn't help, disable selinux in /etc/selinux/config\n" ); exit(EXIT_FAILURE); #else if (config.cpuemu < 3) { /* switch on vm86-only JIT CPU emulation to with non-zero base */ config.cpuemu = 3; init_emu_cpu(); c_printf("CONF: JIT CPUEMU set to 3 for %d86\n", (int)vm86s.cpu_type); error("Using CPU emulation because vm.mmap_min_addr > 0.\n" "You can most likely avoid this problem by running\n" "sysctl -w vm.mmap_min_addr=0\n" "as root, or by changing the vm.mmap_min_addr setting in\n" "/etc/sysctl.conf or a file in /etc/sysctl.d/ to 0.\n" "If this doesn't help, disable selinux in /etc/selinux/config\n" ); } result = alias_mapping(MAPPING_INIT_LOWRAM, -1, LOWMEM_SIZE + HMASIZE, PROT_READ | PROT_WRITE | PROT_EXEC, lowmem); #endif } #else result = alias_mapping(MAPPING_INIT_LOWRAM, -1, LOWMEM_SIZE + HMASIZE, PROT_READ | PROT_WRITE | PROT_EXEC, lowmem); if (config.cpuemu < 3) { /* switch on vm86-only JIT CPU emulation to with non-zero base */ config.cpuemu = 3; init_emu_cpu(); c_printf("CONF: JIT CPUEMU set to 3 for %d86\n", (int)vm86s.cpu_type); } #endif if (result == MAP_FAILED) { perror ("LOWRAM mmap"); exit(EXIT_FAILURE); } #ifdef X86_EMULATOR if (result) { warn("WARN: using non-zero memory base address %p.\n" "WARN: You can use the better-tested zero based setup using\n" "WARN: sysctl -w vm.mmap_min_addr=0\n" "WARN: as root, or by changing the vm.mmap_min_addr setting in\n" "WARN: /etc/sysctl.conf or a file in /etc/sysctl.d/ to 0.\n", result); } #endif /* keep conventional memory protected as long as possible to protect NULL pointer dereferences */ mprotect_mapping(MAPPING_LOWMEM, result, config.mem_size * 1024, PROT_NONE); }