res at colnet.uucp
Tue Jun 25 00:57:25 AEST 1991
In article <389 at kyzyl.mi.org> tkacik at kyzyl.mi.org (Tom Tkacik) writes:
>In article <1991Jun21.215503.26210 at colnet.uucp>, res at colnet.uucp (Rob Stampfli) writes:
>> Correct, with one corrollary: On 3.51 (and I believe 3.5) the first page
>> of virtual memory is read/only and filled with zeros. This was done, I
>> believe, to permit programs that (incorrectly) dereference the NULL pointer
>> to work without causing the segmentation fault Alex describes above. (There
>> Fine, I thought: They just allocated 4K and set up the MMU for R/O access.
>> However, on closer inspection of the hardware, I found what I believe is a
>> prohibition against accessing memory below x80000 in the MMU firmware itself:
>> The firmware appears to use the supervisor/user mode state signal from the
>> 68010 to prohibit user level access to the lower x80000 bytes, regardless of
>> the actual MMU state for page zero. Can anyone confirm or refute this, and
>> if it is so, how does the OS allow read access to page zero?
>I just did a quick test of reading page 0. My program ran fine and printed
>that location 0 does indeed contain the value 0. However, if I tried
>reading from any other location, (even 1), the program chrashed with
>a core dump.
>Perhaps it is not done in the MMU. Instead of writing zeros to the first
>page and giving you read permission, the bus error handler checks to
>see if the bus error was due to a read of location 0, and returns a
>value of zero. I could be done entirely in software.
>I remember trying this test a couple of years ago, and not being able
>to read location 0. This must be a new "feature" of 3.51 (maybe 3.5).
Hmm. Here is the program I used to do the test:
for(i = 0;;i++)
It produces printf output up to i=4092, and then then crashes and burns. I
suspect that if Tom tried accessing location 1 as anything other than a
character, it might have caused a bus error for alignment reasons.
However, based on what Tom said, I tried this program:
j = 0;
j = &k;
for(i = 0; i < 1000000; i++)
k = *j;
The results are quite interesting. With j=&k, the program runs in a
reasonable amount of time, and is cpu bound. With j=0, the program takes
over 15 minutes to run on an idle machine, and most of the time is spent
as system time (I used "time a.out" to try this). This seems to indicate
that Tom's supposition that [ the error interrupt still occurs, but the
Kernel code recovers and returns control to the program in the case of a
read from low memory locations ] is correct. One day, I will have to
delve into the code and see for sure. Now, I wonder: was it just coincidence
that the value read was zero? Perhaps if the code were buried deeply in
other code, and the registers were dirtied, the value returned might be some
other random value.
Rob Stampfli, 614-864-9377, res at kd8wk.uucp (osu-cis!kd8wk!res), kd8wk at n8jyv.oh
More information about the Comp.sys.3b1