Jarred Capellman Putting 1s and 0s to work since 1995

26Feb/120

Radeon 9250 in an SGI Origin 300?

Posted by Jarred Capellman

An idea came up over at Nekochan a few weeks ago to try and see if an RV280 (Radeon 9250) was capable of being installed into an Origin 300. As it stands currently, the Origin 300 does not have a graphics option, so you're limited to VNC to run X on it.

It just so happens I have a Radeon 9250 that's been sitting around since last summer when I was going to try and hack it into a Cobalt Qube 3:

256mb Radeon 9250 PCI

Installed it into my Origin 300, and immediately did a hinv -vm when it booted:

Location: /hw/module/001c16/node
       IP45_4CPU Board: barcode MJP842     part 030-1728-002 rev -D
Location: /hw/module/001c16/Ibrick/xtalk/14
             IO8 Board: barcode MJX813     part 030-1673-003 rev -F
Location: /hw/module/001c16/Ibrick/xtalk/15
             IO8 Board: barcode MJX813     part 030-1673-003 rev -F
4 500 MHZ IP35 Processors
CPU: MIPS R14000 Processor Chip Revision: 1.4
FPU: MIPS R14010 Floating Point Chip Revision: 1.4
CPU 0 at Module 001c16/Slot 0/Slice A: 500 Mhz MIPS R14000 Processor Chip (enabled)
  Processor revision: 1.4. Scache: Size 2 MB Speed 250 Mhz  Tap 0xa
CPU 1 at Module 001c16/Slot 0/Slice B: 500 Mhz MIPS R14000 Processor Chip (enabled)
  Processor revision: 1.4. Scache: Size 2 MB Speed 250 Mhz  Tap 0xa
CPU 2 at Module 001c16/Slot 0/Slice C: 500 Mhz MIPS R14000 Processor Chip (enabled)
  Processor revision: 1.4. Scache: Size 2 MB Speed 250 Mhz  Tap 0xa
CPU 3 at Module 001c16/Slot 0/Slice D: 500 Mhz MIPS R14000 Processor Chip (enabled)
  Processor revision: 1.4. Scache: Size 2 MB Speed 250 Mhz  Tap 0xa
Main memory size: 2048 Mbytes
Instruction cache size: 32 Kbytes
Data cache size: 32 Kbytes
Secondary unified instruction/data cache size: 2 Mbytes
Memory at Module 001c16/Slot 0: 2048 MB (enabled)
  Bank 0 contains 1024 MB (Premium) DIMMS (enabled)
  Bank 1 contains 1024 MB (Premium) DIMMS (enabled)
Integral SCSI controller 0: Version QL12160, low voltage differential
  Disk drive: unit 1 on SCSI controller 0 (unit 1)
Integral SCSI controller 1: Version QL12160, low voltage differential
IOC3/IOC4 serial port: tty3
IOC3/IOC4 serial port: tty4
Integral Fast Ethernet: ef0, version 1, module 001c16, pci 4
  <strong>PCI Adapter ID (vendor 0x1002, device 0x5960) PCI slot 1</strong>
  <strong>PCI Adapter ID (vendor 0x1002, device 0x5940) PCI slot 1</strong>
  <strong>PCI Adapter ID (vendor 0x1077, device 0x1216) PCI slot 1</strong>
  PCI Adapter ID (vendor 0x10a9, device 0x0003) PCI slot 4
  PCI Adapter ID (vendor 0x11c1, device 0x5802) PCI slot 5
IOC3/IOC4 external interrupts: 1
HUB in Module 001c16/Slot 0: Revision 2 Speed 200.00 Mhz (enabled)
IP35prom in Module 001c16/Slot n0: Revision 6.210
USB controller: type OHCI

It picked it up as noted by the bolded PCI entries, but nothing more than that. It was suggested to do an inst -m GFXBOARD=VOYAGER, but I couldn't get my O2 running as a BOOTP server. Maybe another day...

25Feb/120

IRIX Disk Cloning/IRIX Hot Swapping

Posted by Jarred Capellman

Last Sunday I was curious about IRIX root disk cloning, I had done it previously on an SGI Octane with a none root drive, but never on the root drive itself. Since I have 2 SGI O2s and 2 identical Maxtor Atlas II 15k 73gb Ultra 320 drives, it made sense rather than reinstalling everything just to clone it. Sure enough about 20 minutes later, I had an extra duplicate of my SGI O2 IRIX 6.5.30 install with all of my Nekoware packages (BASH, PHP, MySQL etc). Pulled it out and put into my other SGI O2, worked like a charm.

After doing some work on my SGI Origin 300 this morning, I figured I'd replace the failing Maxtor ATLAS 15k 36gb Ultra 320 drive with a brand new Fujitsu MAU3147 15k 36gb Ultra 320 drive. Not to mention the Maxtor had been making a terrible high pitch noise for some time before it ended up in the Origin :)

Fujitsu in the Origin 300 Sled:

Fujitsu MAU ready to go for my Origin 300

After sliding it into my already powered Origin 300, I realized the SCSI ports weren't auto-scanning for changes. Some googling later, I found the Solaris equivalent of probe-scsi-all is scsiha -p 0; on IRIX.

Immediately following that running a hinv command:

4 500 MHZ IP35 Processors
CPU: MIPS R14000 Processor Chip Revision: 1.4
FPU: MIPS R14010 Floating Point Chip Revision: 1.4
Main memory size: 2048 Mbytes
Instruction cache size: 32 Kbytes
Data cache size: 32 Kbytes
Secondary unified instruction/data cache size: 2 Mbytes
Integral SCSI controller 3: Version Fibre Channel QL2200A
Integral SCSI controller 0: Version QL12160, low voltage differential
Disk drive: unit 1 on SCSI controller 0
Disk drive: unit 2 on SCSI controller 0
Integral SCSI controller 1: Version QL12160, low voltage differential
IOC3/IOC4 serial port: tty3
IOC3/IOC4 serial port: tty4
Integral Fast Ethernet: ef0, version 1, module 001c16, pci 4
IOC3/IOC4 external interrupts: 1
USB controller: type OHCI

IRIX found the drive on Controller 0, so I was ready to begin the cloning procedure. Following these steps, 10 minutes later, I had my data copied to the Fujitsu drive and was ready to become my new root drive on my Origin 300.

Pretty cool Silicon Graphics built that in, cloning a Windows system drive is a huge pain natively. Although there is a sweet tool by Arconis if you own a Western Digital on there site, here for free. I used that when I moved off of my RAID 0 stripe of 2 Western Digital Black 500gb drives to the 1TB versions and didn't feel like reinstalling all of my applications including the ones that had limited activations without having to call the company to get them to reset the activations.

Maxtor, you've been good from 2004-2008 and from 2011-2012:

Maxtor ATLAS 15k 36gb drive, finally being retired

25Feb/120

PLINQ after 2 months

Posted by Jarred Capellman

After having used PLINQ and the Concurrent collections for nearly 2 months now, I can say without a doubt, it is definitely the way of the future. This last week I used it extensively in writing a WCF Service that manipulated a lot of data and needed to return it to an ASP.NET client very quickly. And on the flip side it needed to execute a lot of SQL Insertions based on business logic pretty quickly.

As of February 25th, 2012, I think the best approach to writing a data layer is:

  1. Expose all Data Layer access through a WCF Service, ensuring a clear separation between UI and Data Layers
  2. Use of ADO.NET Entity Models tied to SQL Stored Procedures that return Complex Types for objects rather doing a .Where(a => a.Active).ToList()
  3. Process larger result sets with PLINQ, using Concurrent Collections (ie ConcurrentQueue or ConcurrentDictionary) and returning them to the Client (ASP.NET, WP7 etc)

Next step in my opinion would be to add in intelligent App Fabric caching like what Smarty Template Engine did for PHP. Just a clean way to cache pages, while providing flexible ways to invalidate the cache. I am so glad I found that back in 2006 when I was still doing a lot of PHP work.

25Feb/120

SGI Origin 300 FAN Swap and UUCP Fun

Posted by Jarred Capellman

Finally got around to replacing the 4 80mm 40 decibel fans in my Origin 300 this morning. The noise from this one server was enough to travel from the basement inside a rack all the way to the 3rd floor Master Bedroom. Suffice it to say, I definitely couldn't run the server 24/7. Hunting around on Amazon, I found these 80mm Cooler Master fans, not too bad price wise and still put out decent air flow.

New Cooler Master 80mm replacement fans for my SGI Origin 300

Prep for the swap:

My Quad R14k SGI Origin 300

The original fan in case someone needed a part number:

SGI Origin 300 Stock Fan

As I was swapping in the new fans, I realized the fan connector was not the standard ATX style.

Stock Connector:

Stock SGI Origin 300 Fan Connector

Versus the standard ATX connector:

Repacement Cooler Master Fan ATX Connector

Luckily the standard 4 pin Molex power connector for the 2 Ultra 160 drives is right next to the fans, so a little wiring job and voila:

SGI Origin 300 with replacement fans installed

Note, doing it this way will throw an error in the L1 Console and will shut your machine down. A way around it is to simply connect to the Origin 300 over a console connection and type:
env off.

This is dangerous though as the server will not shutdown automatically if a fan fails or the server overheats.

Having said that, it came to my attention that IRIX does not install a Serial/Terminal client by default. The common cu is on the IRIX 6.5 Foundation CD 1 disk. Turn on the Subsystems Only in the IRIX Software Manager and scroll down until you see it. Chances are you're not running a base 6.5 install so you'll also need the first disk of your overlays (6.5.30 Overlay CD 1 in my case) in order to install it to resolve the package conflicts.

After installing you may receive a "CONNECT FAILURE: NO DEVICES AVAILABLE".

Open up vi or your favorite text editor and open up /etc/uucp/Devices

Add in a line:
Direct ttyd2 - 38400 direct

Make sure the spaces are there.

You can also try setting it up via the Serial Manager under the System Manager application.

Afterwards, simply running:
cu -l /dev/ttyd2 -s38400

Allowed me into my L1 console to turn off environment monitoring. Then hit Control + D to get back into the PROM Monitor and hit "1" to start IRIX.

20Feb/120

Quake 2 IRIX > 128mb doesn’t seem to matter (much)

Posted by Jarred Capellman

Just benchmarked my 180mhz R5000SC cpu with only 128mb of memory in Quake 2, it's marginally worse than when I benchmarked the same CPU, but with 1gb of memory. This makes sense though in that back in 1997 when Quake 2 came out, I think I only had just upgraded to 32mb of ram in my Pentium 200 MMX running Windows NT 4. So all the extra ram wouldn't help this scenario.

The one major caveat I noticed was running in a 320x240 window @ 640x480, my O2 ran out of memory and started paging to the Virtual Memory (thank you gmemusage). I tested it twice to make sure, but a word to the wise, do not run Quake 2 in a window if you only have 128mb of memory. I'll test it out with 192mb shortly.

In case anyone was interested here is an updated list:

320x240
128mb - 180mhz R5000SC - 4.1 / 169.6 seconds
1024mb - 180mhz R5000SC - 14.9 / 46.3 seconds
1024mb - 300mhz R5200SC - 18.8 / 36.7 seconds

640x480
128mb - 180mhz R5000SC - 12.2 / 56.3 seconds
1024mb - 180mhz R5000SC - 12.4fps / 55.4 seconds
1024mb - 300mhz R5200SC - 14.5fps / 47.4 seconds

800x600
128mb - 180mhz R5000SC - 10.2 / 67.3 seconds
1024mb - 180mhz R5000SC - 10.3 / 67.2 seconds
1024mb - 300mhz R5200SC - 11.7 / 58.7 seconds

19Feb/120

IIS Fingerprinting with C#

Posted by Jarred Capellman

Continuing my work on my secret project, I've been really intrigued on how nmap's ability to determine the Operating System and Web Server of the host you are scanning. With every test I had done with it, it had always returned exactly what was running, even the more obscure hosts like that of those on IRIX. So I started my research into what would be necessary.

From what I have read so far, you have really two main options for detection. You can either use the return values of an ICMP request or if they are running IIS, using the WebResponse Headers to determine the version of IIS running (Apache will return something like Apache/1.3.23). Digging into ICMP, I realized that would require a good bit more reading so I chose the later for Stage 1 of my detection mechanism.

First off you need to create and return the WebResponse Header:

private string getHttpServerHeader(string ipAddress) {
     WebRequest webRequest = WebRequest.Create("http://" + ipAddress);
     WebResponse webResponse = null;

     string ServerHeader = String.Empty;

     try {
         webResponse = webRequest.GetResponse();
     } catch (WebException ex) {
          if (ex.Response.Headers != null) {
               ServerHeader = ex.Response.Headers["Server"];
          }
     } finally {
          if (webResponse != null) {
               webResponse.Close();
          }
     }

     return ServerHeader;
}

Then using the string result of that function:

private string getWebServerName(string server) {
    // IIS Detection from HTTP.SYS
    if (server.StartsWith("Microsoft-HTTPAPI")) {
        switch(server.Split('/')[1]) {
            case "1.0":
                return "IIS 6.0";
            case "2.0":
                return "IIS 6.0/7.x";
        }
    }

    // IIS Detection not from HTTP.SYS
    if (server.StartsWith("Microsoft-IIS")) {
        return "IIS " + server.Split('/')[1];
    }

    // If no conditional has trapped the Server entry, most likely the Web Server is either Apache or a masked IIS Server
    return server;
}

In reading about Fingerprinting it occurred to me that within IIS itself you can mask it with a custom Server Header like "WS" for instance. I doubt it would prevent a true attack, but it might save a couple bytes per connection over Microsoft-IIS 7.5 :)

18Feb/120

The requested protocol has not been configured into the system, or no implementation for it exists…

Posted by Jarred Capellman

Just got that lovely exception when attempting to do a UDP Socket connection. It's been years since I had done Socket programming and forgot one little gotcha, you have to switch the SocketType to Dgram instead of Stream.

So for instance if you wanted to create a TCP socket object in .NET:

Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

or on UDP:

Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
18Feb/120

Windows Phone 7 ObservableCollection populating a Listbox Asynchronously

Posted by Jarred Capellman

I've been working on a small-ish scale project for the last week now off and on, I'll be announcing it officially probably next week. But anyway, I was running into a problem the main function of the app taking quite a while to process. Given that the performance of the app is entirely dependent on the 3G, 4G, LTE or WiFi connection strength of the phone I wanted to assume the worst when it gets released. Therefore I started looking around for a way to as the the results were returned have the Listbox update asynchronously. Previously with the Windows Phone 7 apps I have developed I simply have had a "Loading" Indicator and a second or two later it would go away, so there really wasn't a need for a "better" solution until now.

Hunting around the WP7 SDK, I came across exactly what I was looking for: Observable Collections. In the "default" solution I had noticed this collection type previously, but always removed it in lieu of a Generic List Collection of whatever object I was using. The only caveat I found when using this approach is that you have to use the Dispatcher to update the collection on the UI Thread.

That being said here's a quick code sample:

In your Button or Page_Load Event set your Listbox ItemSource to the ObservableCollection you're going to populate:

lstBxResults.ItemsSource = App.ViewModel.Results;

Inside your ViewModel loop or asynchronously task (like a WCF service call for instance), wrap the addition of the result inside a Dispatcher Invoke:

System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() => {
     Results.Add(new YourObject(e.Result));
});

With those 2 blocks you'll have your Listbox updated as they get added to the ObservableCollection from whatever time consuming task your phone is doing. Hope that helps someone out.

17Feb/120

Quake 2 IRIX – 180mhz R5000SC vs 300mhz R5200SC

Posted by Jarred Capellman

I got a 300mhz R5200SC CPU (the highest R5k series CPU for the O2) for my main Silicon Graphics O2. I ran before and after Quake 2 results out of curiosity if it would make a big difference having nearly 2X the mhz and that the CRIME graphics core is tightly integrated with the CPU.

Using the following commands on the console:

timedemo 1
map demo1.dm2

Here's the results:

320x240
180mhz - 14.9 / 46.3 seconds
300mhz - 18.8 / 36.7 seconds

640x480
180mhz - 12.4fps / 55.4 seconds
300mhz - 14.5fps / 47.4 seconds

800x600
180mhz - 10.3 / 67.2 seconds
300mhz - 11.7 / 58.7 seconds

Kind of surprised at the results, I'll be testing my 180mhz R5000PC vs 180mhz R5000SC shortly to see what if any difference the Level 2 cache makes.

12Feb/120

SGI O2 – Maxed out Memory

Posted by Jarred Capellman

Found a guy on Craigslist who was selling his O2, didn't know the specs other than it was not a R10k or R12k model, but offered it for $50. The going rate on eBay for O2 parts is generally higher than that, so I took a gamble. Surprisingly, the O2 was the lowest end CPU, but had 8 128mb sticks of memory, the max you can pop in an O2. One pair of these go for over a hundred bucks on eBay. I migrated all of my memory out of my O2 and swapped it in, voila 1GB for $50 and now I've got an "extra" O2 that I'll probably use to record guitar riffs.

Silicon Graphics O2 showing the 1GB of RAM

I tried Quake II, it boots up a little bit quicker, but FPS wise, I didn't notice a difference.

12Feb/120

Quake II on IRIX

Posted by Jarred Capellman

I figured after attempting to compile SDLQuake and running into x86 assembly, UDP and linking issues I decided to try the "official" IRIX port from SGI. Oddly enough, Quake II runs at 640x480x16 with full textures on my Silicon Graphics O2. Feeling adventurous, I wanted to see if it would play with the x86 Windows 3.20 version. Sure enough, I was able to play with an IRIX hosted game (it would probably work the other way as well) with my Windows 7 workstation.

Quake II on my O2

On a side note, I got SDLQuake to get all the way to the linking stage before giving up on it. For whatever reason using -lSDL was not including what looks like X11 or OpenAL libraries. I included both of those libraries and was still getting the errors.

11Feb/120

Quake on IRIX

Posted by Jarred Capellman

Finally got Quake working on my Silicon Graphics O2. Using the "official" SGI port from September 1997, it runs fairly smooth at 1024x768x16.

Quake on my SGI O2

It did bring up old memories of my first LAN party in Summer of 1998 playing Quake, particularly E1M7 as seen in the picture. Definitely makes me want to have a Retrogaming LAN with Quake or Descent.

8Feb/120

Getting a picture from Android to a WCF Service

Posted by Jarred Capellman

Had a fun time today getting a picture taken from an Android 2.3.4 HTC Vivid to my Mobile WCF Platform. Oddly enough, I could not find any tutorials on it for Monodroid like there are for MonoTouch. Piecing together several stackoverflow posts, I finally figured it out. Here is a possible solution (most likely not the best):

At the top of your class, add the following:

private string _imageUri;
private ImageView imageView;

private Boolean isMounted {
            get {
                return Android.OS.Environment.ExternalStorageState.Equals(Android.OS.Environment.MediaMounted);
            }
        }

Inside your Button Click Event:

     var uri = ContentResolver.Insert(isMounted ? Android.Provider.MediaStore.Images.Media.ExternalContentUri : Android.Provider.MediaStore.Images.Media.InternalContentUri, new ContentValues());
     _imageUri = uri.ToString();
     var i = new Intent(Android.Provider.MediaStore.ActionImageCapture);
     i.PutExtra(Android.Provider.MediaStore.ExtraOutput, uri);
     StartActivityForResult(i, 0);

Right below your Click Event function (or anywhere inside the Activity Class you're in):

protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) {
            if (resultCode == Result.Ok && requestCode == 0) {
                imageView = FindViewById<ImageView>(Resource.Id.ivThumbnail);
                imageView.DrawingCacheEnabled = true;

                imageView.SetImageURI(Android.Net.Uri.Parse(_imageUri));

                btnUploadImage.Visibility = ViewStates.Visible;
            }
        }

Then inside your "Upload Button Click" function:

Bitmap bitmap = imageView.GetDrawingCache(true);
MemoryStream ms = new MemoryStream();

// Note anything less than 50 will result in very pixelated images from what I've seen
bitmap.Compress(Android.Graphics.Bitmap.CompressFormat.Jpeg, 100, ms);

// At this point set your Byte[] variable/property with ms.ToArray();
// for instance I have a SyncFile object with a FileData Property, so I use
// SyncFile sFile = new SyncFile() { FileData = ms.ToArray(); };

Effectively this code captures a picture, puts it in an ImageView as a thumbnail on the Activity and then upon hitting your Upload Button it converts the image into a Byte Array after compressing it (or not like in my case) and from there call your WCF service upload function.

Hopefully that helped someone out.

6Feb/120

Accessing Activity from TabActivity using Monodroid

Posted by Jarred Capellman

Monodroid gave me headaches this afternoon, trying to mimic the Pivots on Windows Phone 7 on Android using the TabActivity. You would think you access an Activity after attaching it to a TabActivity. Well the answer is you can, but figuring it out on Monodroid will make your hair go gray. After digging through the Java based Android Documentation I finally figured it out. I don't know if this is the right way, but it works:

Declare an enumeration object with each of your tabs:

public enum TABS {
   BasicInformation = 0,
   Detailinformation = 1,
   OptionalInforation = 2
};

Then add an abstract class to each of your Activity Objects:

public abstract class MyDroidActivity : Activity {
   public abstract bool SaveActivity();

   // Any other custom code you had
}
</code>

<strong>Then inside your inherited <code>Activity</code>:</strong>
<code>
public class BasicInfoActivity : MyDroidActivity {
   public override bool SaveActivity() {
         // Error handling to return false if for instance the fields weren't populated
   }
}

Then in your TabActivity Class:

private void SaveAllTabs() {
   TabHost.CurrentTab = (int)TABS.BasicInformation;

   BasicInformation biTab = (BasicInformation)LocalActivityManager.GetActivity(TabHost.CurrentTabTag);

if (!biTab.SaveActivity()) {
return;
}

// And continue with your other Tabs
}

Not the most elegant, but works. The inherited class and enumerations are not necessary, but helps keep things in order, especially if you have a larger application in my opinion.

4Feb/122

Computer Speed…Well…Relatively

Posted by Jarred Capellman

Been working on my Silicon Graphics O2 a lot and surprisingly it's pretty responsive for directory browsing, C/C++ source code editing/compiling and software installation. For a 16 year old 180mhz machine with only 192mb of memory I am really shocked what an optimized and lightweight operating system can do. For web browsing, FLAC music playing etc, it won't stand up against my Phenom II X6, but for everything I'm doing, it is neck and neck.

This thought got my thinking, everyday new cpus/apus, gpus etc come out, the last generation is put into bargain bins or rebadged as a lower end part of the next generation. I'm voting to rethink "computer performance", at least its definition. If someone running Microsoft Word, Zune and Chrome on a Windows 7 machine with 6 cores and 16gb ram notices no difference when he or she is on 2 core, 4gb ram system, then why justify the badging of that machine as a lowerend? To me it is all relative to what you're actually doing. I can browse to a C++ file from a terminal window, open it in vi and start editing on my SGI O2 faster than I could open up Visual Studio 2010, then browse to the project and start coding on my Phenom II system. It saddens me to know that so many people will frown upon not top of the line specs even if they are only going to use 50% of the power available. Gluttony it seems has taken hold of consumers...

Tagged as: , , , 2 Comments