Date: Mon, 11 Mar 1996 22:22:06 +0100 (MET) From: J Wunsch <j@uriah.heep.sax.de> To: freebsd-current@FreeBSD.org (FreeBSD-current users) Subject: system() broken while mmap()ing something Message-ID: <199603112122.WAA07526@uriah.heep.sax.de>
next in thread | raw e-mail | index | archive | help
There's been a long and ongoing discussion about the reasons why recent XFree86(tm) servers don't run under FreeBSD-current. With Xkb enabled, they hang the entire system, or cause other weird behaviour. All the other systems supported by XFree86 don't suffer from this, and it's easily provable that it's not related to phkmalloc (e.g. by using the original gnumalloc again). David Dawes has been boiling down this to: ----- Forwarded message from David Dawes ----- From: David Dawes <dawes@rf900.physics.usyd.edu.au> Message-Id: <199603111058.VAA20801@rf900.physics.usyd.edu.au> Subject: Re: 3.1.2Db S3 freebsd-current To: beta@XFree86.Org Date: Mon, 11 Mar 1996 21:58:31 +1100 (EST) In-Reply-To: <199603110802.JAA05393@uriah.heep.sax.de> from "J Wunsch" at Mar 11, 96 09:02:18 am >Do i understand it right that the system() call happens while /dev/mem >is kept mmap()ed inside the X server? Perhaps this is something >that's unique to the X server environment. (Other programs might >either not mmap /dev/mem at all, or at least, they don't fork.) That is correct. The mmap happens when the display is initialised. The system() call happens when the input devices are initialised, and this happens after the display is initialised. The mmap area isn't completely lost -- at least reads (I tried xwd -root) are *almost* OK with the S3 server when using a 64k VGA aperture. I've attached a test program that does demonstrate a problem. The program isn't what I originally had in mind. This one mmaps the BIOS, and in three phases it "writes" to it, and reads back the result. Since the BIOS is read-only, mismatches should occur in each phase, however on FreeBSD-current, the last phase (after a system("/bin/ls > /tmp/l")) reports no mismatches. On FreeBSD-2.0.5, mismatches are correctly reported at each phase. David ----------- #include <stdio.h> #include <sys/mman.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #define SIZE (4 * 1024) #define BASE 0xC0000 main() { int fd = -1; unsigned char *base = NULL; unsigned char *save = NULL; int i; int mismatch = 0; if ((fd = open("/dev/mem", O_RDWR)) < 0) { perror("can't open /dev/mem"); exit(1); } base = (unsigned char *)mmap((caddr_t)0, SIZE, PROT_READ | PROT_WRITE, MAP_FILE, fd, (off_t)BASE); if ((int)base == -1) { perror("can't mmap vga memory"); exit(1); } #ifdef SAVE_NEEDED /* Save the existing memory contents */ if ((save = (unsigned char *)malloc(SIZE)) == NULL) { perror("malloc failed"); exit(1); } memcpy(save, base, SIZE); #endif /* Write a pattern */ for (i = 0; i < SIZE; i++) base[i] = (i & 0xFF) ^ (i >> 8); /* Read it back */ for (i = 0; i < SIZE; i++) if (base[i] != ((i & 0xFF) ^ (i >> 8))) { #ifdef VERBOSE printf("before: byte %5d doesn't match -- %3d != %3d\n", i, base[i], (i & 0xFF) ^ (i >> 8)); #endif mismatch++; } printf("before: %5d mismatches\n", mismatch); /* Clear the pattern */ memset(base, 0, SIZE); /* Write a pattern */ for (i = 0; i < SIZE; i++) base[i] = (i & 0xFF) ^ (i >> 8); /* Read it back */ mismatch = 0; for (i = 0; i < SIZE; i++) if (base[i] != ((i & 0xFF) ^ (i >> 8))) { #ifdef VERBOSE printf("middle: byte %5d doesn't match -- %3d != %3d\n", i, base[i], (i & 0xFF) ^ (i >> 8)); #endif mismatch++; } printf("middle: %5d mismatches\n", mismatch); /* Clear the pattern */ memset(base, 0, SIZE); /* Run something harmless */ system("/bin/ls > /tmp/l"); /* Write a pattern */ for (i = 0; i < SIZE; i++) base[i] = (i & 0xFF) ^ (i >> 8); /* Read it back */ mismatch = 0; for (i = 0; i < SIZE; i++) if (base[i] != ((i & 0xFF) ^ (i >> 8))) { #ifdef VERBOSE printf("after: byte %5d doesn't match -- %3d != %3d\n", i, base[i], (i & 0xFF) ^ (i >> 8)); #endif mismatch++; } printf("after: %5d mismatches\n", mismatch); #ifdef SAVE_NEEDED /* unmap, remap, and restore the video memory */ munmap(base, SIZE); base = (char *)mmap((caddr_t)0, SIZE, PROT_READ | PROT_WRITE, MAP_FILE, fd, (off_t)BASE); if ((int)base == -1) { perror("can't mmap vga memory"); exit(1); } memcpy(base, save, SIZE); #endif munmap(base, SIZE); exit(0); } ----- End of forwarded message from David Dawes ----- -- cheers, J"org joerg_wunsch@uriah.heep.sax.de -- http://www.sax.de/~joerg/ -- NIC: JW11-RIPE Never trust an operating system you don't have sources for. ;-)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199603112122.WAA07526>