Patch hosted memory allocation. some systems will not allow AROS to allocate > 1024MB...
[AROS.git] / arch / all-unix / bootstrap / memory.c
blobebd79b550647a989a2f5aeb74c3eae00721dbb61
1 #include <stdlib.h>
2 #include <unistd.h>
3 #include <sys/mman.h>
5 #include "bootstrap.h"
7 #ifndef MAP_32BIT
8 #define MAP_32BIT 0
9 #endif
11 static void *data = NULL;
12 static void *code = NULL;
13 static size_t code_len = 0;
15 static void *RAM32 = NULL;
16 static size_t RAM32_len = 0;
18 #if (__WORDSIZE == 64)
19 static void *RAM = NULL;
20 static size_t RAM_len = 0;
21 #endif
24 * Allocate memory for kickstart's .code and .rodata. We allocate is as writable
25 * because we will load the kickstart into it. We will enable execution later in SetRO().
26 * We have to use mmap() and not posix_memalign() here because posix_memalign()
27 * does not pad the allocated memory up to next page boundary. As a result, setting
28 * it read-only will affect the whole page, but the page will still have some unallocated
29 * space which can be reused by malloc().
30 * This causes DisplayError() function to crash on iOS. This also may cause similar effects
31 * on other systems.
34 void *doMMap(void **addr_store, size_t *size_store, size_t len, int prot, int flags)
36 /* There's no sense to set MAP_SHARED for ROM */
37 void *ret = mmap(NULL, len, prot, flags, -1, 0);
39 if (ret == MAP_FAILED)
40 ret = NULL;
41 else
43 if (addr_store)
44 *addr_store = ret;
45 if (size_store)
46 *size_store = len;
48 return ret;
51 void *AllocateRO(size_t len)
53 /* There's no sense to set MAP_SHARED for ROM */
54 return doMMap(&code, &code_len, len, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE|MAP_32BIT);
58 * Disable write and enable execution.
59 * We actually have to do this in two steps because some systems
60 * (Apple iOS) do not allow read-write-execute permissions.
62 int SetRO(void *addr, size_t len)
64 return mprotect(addr, len, PROT_READ|PROT_EXEC);
68 * Allocate kickstart's .data and .bss. Nothing is executed from there, so we
69 * don't have to take some special care about it. Simple malloc() is enough here.
71 void *AllocateRW(size_t len)
73 data = malloc(len);
74 return data;
78 * These routines allocate memory usable as AROS ram. This means it
79 * needs to have full permissions.
80 * Yes, iOS will silently mask out PROT_EXEC here. This is bad.
81 * Well, iOS will be a little bit special story in InternalLoadSeg()...
83 void *AllocateRAM32(size_t len)
85 return doMMap(&RAM32, &RAM32_len, len, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_SHARED|MAP_32BIT);
88 #if (__WORDSIZE == 64)
89 void *AllocateRAM(size_t len)
91 return doMMap(&RAM, &RAM_len, len, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_SHARED);
93 #endif
95 void Host_FreeMem(void)
97 munmap(code, code_len);
98 free(data);
99 #if (__WORDSIZE == 64)
100 if (RAM)
101 munmap(RAM, RAM_len);
102 #endif
103 munmap(RAM32, RAM32_len);
105 free(SystemVersion);
106 if (KernelArgs)
107 free(KernelArgs);