Scientific Visualization Using imagery to aid humans in understanding a complicated phenomenon

advertisement
Scientific Visualization
Using imagery to aid humans in
understanding a complicated
phenomenon
An example from our class
•
•
•
•
•
•
Student asked about ‘task_union’ objects
“Can stack overwrite process descriptor?”
Maybe we ought to be worried about this
If descriptor gets corrupted, then: crash!
System protects against users crashing
But can’t protect if kernel code crashes!
One picture is worth 1000 words
•
•
•
•
•
•
•
‘modules’ let us study a running kernel
We could look at a ‘task_union’ object
But there are several design-issues
How much ‘data’ will fit on one screen?
How can we make ‘data’ understandable?
How can we make a picture be ‘esthetic’?
How much effort are we willing to devote?
Doing data amalgamation
•
•
•
•
•
•
•
Size of a ‘task_union’ is 8KB
Size of standard text screen is 2000 chars
Not enough display-space for these bytes
Idea: use a coarser subdivision of the data
Subdivide a ‘task_union’ into quadwords
Each quadword is 8-bytes in size
So total number of quadwords is 1024
Screen layout
• Standard text screen: 25 rows, 80 columns
• Arrange 1K quadwords: 16 lines, 64 cells
• Enough room left for a title and a legend
title
legend
data
Module’s design
•
•
•
•
•
Build a ‘/proc’ module
Can use a ‘wizard’ for Rapid Development’
Our ‘proc_read()’ function needs two parts
1) prepare the selected data-amalgation
2) draw screen display: title, data, legend
The ‘amalgamation’ step
• Use an array of byte-size elements:
• unsigned char glyph[ NR_CELLS ];
• Define manifest constants:
#define GRANULARITY 8
#define SZ sizeof( union task_union )
#define NR_CELLS (SZ/GRANULARITY)
Location of ‘task_union’ object
• We can use value of ‘current’ macro:
char *cp = (char*)current;
(This creates pointer to the object’s base)
An amalgamation algorithm
int
i, j;
for ( i = 0; i < NR_CELLS; i++)
{
unsigned char total = 0;
for (j = 0; j < GRANULARITY; j++)
total |= cp[ i * GRANULARITY + j ];
glyph[ i ] = ( total ) ? ‘+’ : ‘-’;
}
Algorithm rationale
• ‘clean’ memory will show up as ‘-’
• ‘dirty’ memory will show up as ‘+’
• But this won’t show areas we care about!
• We want to see the ‘process descriptor’
• And we want to see the kernel stack
A ‘secondary’ algorithm
• Mark descriptor cells with letter ‘D’
• And mark stack cells with letter ‘S’
• But which are these cells in ‘glyth[]’ array?
Glyphs for descriptor and stack
• Process descriptor starts at offset zero
• Descriptor’s ‘size’ tell where it ends
int d_top = sizeof( struct task_struct )/8;
for (i = 0; i < NR_CELLS; i++)
if ( i < d_top ) glyph[ i ] = ‘D’;
• Stack-area ends where task_union ends
• But where does stack-area start?
Reading cpu’s ESP register
•
•
•
•
For IA-32 architectures, ESP = stacktop
Need assembly language to read registers
Here’s how to write it for gcc:
Declare a memory-variable:
unsigned long tos;
Copy ESP register-value into variable ‘tos’:
asm(“ movl %%esp, %0 “ : “=m” (tos) );
‘kernel stack’ glyphs
Task kernel-stack begins at address in ‘tos’
int
s_org = ( tos / GRANULARITY );
for ( i = 0; i < NR_CELLS; i++)
if ( i >= s_org ) glyph[ I ] = ‘S’;
Drawing the screen display
•
•
•
•
•
Use ‘len’ variable to count output bytes
Initialize ‘len’ to zero
Draw to area whose address is in ‘buf’
Use ‘sprintf()’ function to draw into ‘buf’
Increment ‘len’ as more bytes are drawn:
len += sprintf( buf+len, “\nMy Title\n” );
Use loop to draw data-glyphs
Show 64 glyphs per line:
for (i = 0; i < NR_CELLS; i++)
{
if ( ( i % 64 ) == 0 ) len += sprintf( buf+len, “\n” );
len += sprintf( buf+len, “%c”, glyph[ i ] );
}
Understanding and Esthetics
•
•
•
•
Picture looks ‘upside down’
Shows descriptor higher than stack
Also doesn’t show where data is located
Can we draw it so that:
it’s easier to understand?
it displays more information?
it is prettier to look at?
The visualization ‘demo’
• Module ‘visual.c’ is on our course website
• Compile module using command
$ make visual.o
• Install module using command
$ /sbin/insmod visual.o
• Show ‘task_union’ object using command
$ cat /proc/visual
Project #2
•
•
•
•
•
Write a Linux character device-driver
Driver’s device-file will be: /dev/physmem
Will allow programs to ‘read’ physical ram
For safety: device should be ‘read-only’
Programs can treat ram as ordinary file
‘Physical’ versus ‘Virtual’
• Linux maps physical memory to top 1-GB
• Physical memory starts from 0x00000000
• Kernel ‘sees’ it as starting at 0xC0000000
High_memory
Virtual
address
space
Physical
RAM
4GB
Download