0001
0002 #include <stdio.h>
0003 #include <stdlib.h>
0004 #include <signal.h>
0005 #include <sys/mman.h>
0006 #include <longjmp.h>
0007
0008 #ifdef __i386__
0009
0010 static jmp_buf buf;
0011
0012 static void segfault(int sig)
0013 {
0014 longjmp(buf, 1);
0015 }
0016
0017 static int page_ok(unsigned long page)
0018 {
0019 unsigned long *address = (unsigned long *) (page << UM_KERN_PAGE_SHIFT);
0020 unsigned long n = ~0UL;
0021 void *mapped = NULL;
0022 int ok = 0;
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 if (setjmp(buf) == 0)
0033 n = *address;
0034 else {
0035 mapped = mmap(address, UM_KERN_PAGE_SIZE,
0036 PROT_READ | PROT_WRITE,
0037 MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
0038 if (mapped == MAP_FAILED)
0039 return 0;
0040 if (mapped != address)
0041 goto out;
0042 }
0043
0044
0045
0046
0047
0048
0049 if (setjmp(buf) == 0) {
0050 *address = n;
0051 ok = 1;
0052 goto out;
0053 } else if (mprotect(address, UM_KERN_PAGE_SIZE,
0054 PROT_READ | PROT_WRITE) != 0)
0055 goto out;
0056
0057 if (setjmp(buf) == 0) {
0058 *address = n;
0059 ok = 1;
0060 }
0061
0062 out:
0063 if (mapped != NULL)
0064 munmap(mapped, UM_KERN_PAGE_SIZE);
0065 return ok;
0066 }
0067
0068 unsigned long os_get_top_address(void)
0069 {
0070 struct sigaction sa, old;
0071 unsigned long bottom = 0;
0072
0073
0074
0075
0076
0077
0078
0079
0080 unsigned long top = 0xffffd000 >> UM_KERN_PAGE_SHIFT;
0081 unsigned long test, original;
0082
0083 printf("Locating the bottom of the address space ... ");
0084 fflush(stdout);
0085
0086
0087
0088
0089
0090 sa.sa_handler = segfault;
0091 sigemptyset(&sa.sa_mask);
0092 sa.sa_flags = SA_NODEFER;
0093 if (sigaction(SIGSEGV, &sa, &old)) {
0094 perror("os_get_top_address");
0095 exit(1);
0096 }
0097
0098
0099
0100
0101 for (bottom = 0; bottom < top; bottom++) {
0102 if (page_ok(bottom))
0103 break;
0104 }
0105
0106
0107 if (bottom == top) {
0108 fprintf(stderr, "Unable to determine bottom of address "
0109 "space.\n");
0110 exit(1);
0111 }
0112
0113 printf("0x%lx\n", bottom << UM_KERN_PAGE_SHIFT);
0114 printf("Locating the top of the address space ... ");
0115 fflush(stdout);
0116
0117 original = bottom;
0118
0119
0120 if (page_ok(top))
0121 goto out;
0122
0123 do {
0124 test = bottom + (top - bottom) / 2;
0125 if (page_ok(test))
0126 bottom = test;
0127 else
0128 top = test;
0129 } while (top - bottom > 1);
0130
0131 out:
0132
0133 if (sigaction(SIGSEGV, &old, NULL)) {
0134 perror("os_get_top_address");
0135 exit(1);
0136 }
0137 top <<= UM_KERN_PAGE_SHIFT;
0138 printf("0x%lx\n", top);
0139
0140 return top;
0141 }
0142
0143 #else
0144
0145 unsigned long os_get_top_address(void)
0146 {
0147
0148 return 0x7fc0002000;
0149 }
0150
0151 #endif