So my uh ‘friend’ that got into trouble when he found out that his ‘dedicated’ machine turned out to be a VM which he couldn’t launch nested KVM VM’s, and instead found that User Mode Linux (UML), would allow them to run their touchy ancient Linux application in a psudo VM/Container. Well they finally bit the bullet and decided to move to something better.
And by better, it was cheaper. And why was it cheaper? Because it is even a more restricted VM.
So naturally the panic call was made, because TUN/TAP networking was not permitted in this new VM. So what to do.
Well, keeping in mind how Qemu gets around this problem, it binds in a copy of SLiRP. And it turns out that UML can actually call SLiRP directly! So cool we have an ‘out’. First things first, we need SLiRP on the host machine. I’m old, so that means I build it from source.That means I’m downloading slirp-1.0.16.tar.gz, along with the 1.0.17 patch. I’m not sure if I need to go into how to extract source, patch, running configure and compiling.
One thing of note is that you really really really want to set the “FULL_BOLT” option either in the Makefile, or in config.h
With SLiRP built, I just copy it into /usr/local/bin .. I’m sure there is packages and stuff out there, but heh I’m old.
OK next up I make a small script to call SLiRP, in this case, I’m going to redirect port 80 directly into the VM. And for a test port 2323 which then goes into port 23 (why not ssh? .. sigh don’t go there).
So over in my work on porting Dynamips to MinGW, I’ve created a version of SLiRP that sends and receives data over UDP. In retrospect, something I should have done a long time ago, as it makes troubleshooting it easier as now if it were to crash it’s a stand alone program, so it won’t crash the emulator.
The good news is that I’ve been able to copy files into the virtual router using HTTP. I’ve even been able to access my OS/2 machine over FTP and load a file!
In addition, a 7200 with idle performs MUCH better than a 1700 without idle. There is something up with ptask, and only dispatching packets every so often. I’m guessing it’s done that way for a reason.
Also one other cool IOS trick I learned today is that you can redirect to a file resource! Say you want that ‘show tech-support’ as a file on the disk? No problem!
show tech-support | redirect disk0:tech.txt
And of course the newer versions of IOS have a ‘do’ command that you can run from config mode to execute user commands.
Line User Host(s) Idle Location
* 0 con 0 idle 00:00:00
2 vty 0 idle 15:24:11 10.0.2.2
3 vty 1 idle 14:59:56 10.0.2.2
4 vty 2 idle 13:43:44 10.0.2.2
5 vty 3 idle 11:23:44 10.0.2.2
This will listen on port 20001, and send traffic to 127.0.0.1 on port 20000. Easy right?
Manually interfacing from the hypervisor can be the ‘fun’ part. I haven’t tested with any of the tools, as I don’t know if they will let you leave something ‘listening’ that isn’t connected. For my tests I end up building something with their UI, then loading up my hypervisor that logs, and seeing what it is actually doing so I can inject stuff like this:
This creates a udp nio, and attaches it onto the virtual etherswitch S1, and puts it on VLAN 1. As you can see it listens on UDP port 20000, which is where slirp_rdr is setup to send it’s data to, and it’ll send to 20001 where slirp_rdr is listening.
I’ve hard coded port 42323 to telnet into 10.0.2.15. As always SLiRP is hard coded to have the following ip address schema:
Be sure to set your router to 10.0.2.15/24 for this to work, and add 10.0.2.2 as your default gateway.
The ONLY address that will respond to ping is 10.0.2.2 . This is just the way SLiRP is. HTTP and TCP based stuff works best, things like PPTP will not. It’s really hit and miss, but the cool thing is that it doesn’t require any device drivers, it’s all user mode code!
PCem is different from other emulators in that when it starts up, reboots it’ll tear itself apart, and re-kick all the components. Normally other emulators do this once, and as a result I never noticed that slirp_exit doesn’t actually purge the socket state. And calling the socket teardown call causes a mbuf explosion in the code. Sadly GDB is pretty useless trying to debug it, since it’s claiming all the structure members don’t exist. Very strange.
Luckily I could duplicate the debug feature to go though current socket redirects, and close the sockets on the Windows side with a simple closesocket.
In this version I’ve setup the following TCP port redirects:
So PCem is an incredible emulator for the IBM PC platform. One thing that has been missing, and really missed has been networking. So a while ago, SA1988 came up with a patch that incorporated the BOCHS ne2k.cc into PCem.
So as requested, I took the copy of SLiRP I’ve used in SIMH, Cockatrice and Previous, and got it working in PCem.
This has to be one of the easier ports since PCem doesn’t use threads. But yes, it appears to work, although I haven’t done any major testing.
For those who want to experiment, here is a binary/source blob of the project. Right now we are just past the OMG it compiled phase to OMG it SENT and RECEIVED data phase.
If anyone wants to play, the NE2000 is set to 0x300 IRQ 10.
And you need to manually add the following to your pcem.cfg file:
So I got this request to add in some SLiRP to Previous, the NeXT computer emulator. Sadly work got in the way, and I trashed my windows dev machine. To make it worse I also trashed my MacBook Air, but with a bit of screwing around I got X-code removed, and re-installed.
So Here is my wonderful work, some 50 lines of code + the SLiRP from Cockatrice all hacked up.
ICMP to 10.0.2.2 seems to work fine, UDP seems to not work, so no DNS. I don’t know why either. I can telnet to my BBS just fine, which is about all the testing I’ve done.
Inbound TCP seems to be broken too, but I could be initializing slirp_redirect incorrectly too.
so I got it to “work” on OS X….. well 10.6 in VMWare. I have no idea if this means it will work on your setup.
If AppleTalk packets get passed early in the boot stage, it will crash.
If JIT is enabled, it will crash
Performance is horrible, I’m getting 150k/sec on my LAN, Basilisk II with no JIT blows this thing away.
Honestly I feel kind of hesitant releasing this, but I know it was desired, and I guess it’ll help someone somewhere being able to have an easier conversation… So I’m going to upload my source tree, including binaries built with GCC 4.0 & 4.2 with either O2 or Os flags. I’m not sure which is more stable/faster…So here is my source tree. Sorry you still have to deal with the changing password thing, but cancel it, and it’ll tell you the password.Other lessons learned… SheepShaver’s segfault model only works when the CPU thread is the main thread. Even though you “can” stuff the CPU into a subordinate thread, it doesn’t play nice once it segfaults, it’ll just spin waiting for something that clearly isn’t going to happen.In config.h I added in USEGLOBALvideo as a way for main to call the screen update to end the vast majority of pool leakage. I also added SHEEPSHAVER_CURSOR to enable the hardware cursor. I was having some issues installing OS 8.x when the ‘hand’ was drumming the fingers waiting for the OS to install it crashed many times, while disabling the hardware cursor made it play nicer. Maybe it’s my setup, I’m not sure.
Also in this version I don’t read .sheepshaver_prefs but rather sheepshaver_prefs in the current working directory. I didn’t want to trash any other prefs. I have to test again but I think this should work on 10.10 … As I found out the hard way x86_64 binaries can no longer mess with the zero page, so this is a 32bit only build, but I was running it with my SLiRP fixes ok on my macbook air.
This hasn’t been extensively tested. I hate to even call it tested, I just copied a few MB of stuff over an NT server running AppleTalk,a nd viewed some flash video with Internet Explorer 5.1 …. I’m sure there are PLENTY of things broken. JIT should work with these binaries (Quake 1 is quite playable), but DOOM crashes hard (isn’t it a 68k binary?). DOOM runs ok on Basilisk II so does it matter?
If you want speed, JIT + SLiRP is the way to go. Since this is basically the same as the version I was using with BasiliskII I think it’s more stable than the generic version as I could at least run all kinds of programs with some of my fixes vs the ‘stock’ github version.
I should add that I’ve been primarily testing with that PowerMac 9500 v1 ROM, along with MacOS 8.6. I found 8.0 and 8.1 too unstable, 7.x & 9.0.4 uninteresting.
To get around the early crashing while booting 8.6, I rigged it to drop the first 30 packets. I’ve successfully booted 10/10 times, so I’m almost OK with that. I’d rather know when the OS is ok, and go with that, but I’m not sure. I thought about a timer, and say ignore the network for the first 30 seconds, and maybe that is the better way to go. When you launch this you’ll see some message updating about packets and “wait for 30->” and a number… once it reads “wait for 30->30” , the message will no longer update, and it’ll start to forward packets into the machine. You probably will have to disable and re-enable AppleTalk from the chooser to see the network (or I had to). You may have to get creative to generate the needed packets on your network to get it over 30, as those are packets received. Broadcast packets work too, so maybe you can work with that… As long as Sheep Shaver isn’t alone something should be looking for other devices.
Well I was shuffling files back and forth into Shoebill, and with the advent of Ethernet support, I decided I wanted to build an AppleTalk network. This endeavor seems to have taken a life of it’s own.
So, the first thing I did was tear into minivmac, as I figured it would be the easiest to modify, as ‘mini’ is in it’s name. But it’s more geared to LocalTalk. From it’s readme:
It does this by converting the LocalTalk packets between SDLC frames in the virtual machine to LocalTalk Over Ethernet (LTOE) packets. These LTOE packets will be sent out the host machines Ethernet interface and will reach any other machine on the LAN. LTOE packets are not routable and not recognized by EtherTalk devices.
Which is pretty creative, but I want to talk to A/UX, Windows NT and Cisco routers. So this isn’t going to work out for me.
The next other ‘big’ names in Macintosh emulation are Basilisk II and SheepShaver. Both of which are from Christian Bauer which is a sizable download (or so I thought) and has a very confusing release versions for Windows. So I went ahead and tried BasiliskII, which only does some native networking via a TUN/TAP & bridge solution (which is really popular solution for plenty of UNIX based stuff), which personally I don’t really care for. The Windows version does support SLiRP, but for some strange and annoying reason it always crashes when I try to download anything big. As a matter of fact, the Windows version crashes, a lot!
While digging around for various builds of Basilisk II, I found the defunct sourceforge page, which is thankfully still up. And there I found the 0.8 and 0.9 release source code, which weighs in at a tiny 350kb in size. This is something I could probably dive into. So I went ahead and tried to build it on a Debian 7 x86 VM. And much to my surprise, after altering configure to accept GCC 4.7, and forcing it to turn X11 on (I don’t know why it kept failing to detect it), I was able to build a binary in no time. Even better, it worked!
So the first few goals were simple, I wanted to take 0.8 and remove it’s dependency on X11,and make it use SDL 1.2. Why not SDL 2.0? Well 2.0 is more about 3d space, and even to render a flat framebuffer it uses streaming textures. Which is too heavy for me, so I’m sticking with 1.2. I took a bunch of code from SDLQuake, and after a while of bashing it around, I was able to open a window, and capture some ouput from the framebuffer. With even more bashing around I got it to work correctly. I did make some small tweaks though, it only supports 8bit depth. But I’m interested in networking, so 256 colours is fine by me. Now that i could see what I was doing, I was able to then re-compile on OS X, and I was greeted with the Mac Boot screen. The harder part was Windows, as the system code written by Lauri Pesonen who did an excellent job of porting BasiliskII to Windows, but to say their code took 100% advantage of the Win32 API would be an understatement.. And I wanted something more pure to being SDL so I really couldn’t use much of that code. And what code I could find it was for far later versions. However with enough pushing I did finally get BasiliskII to boot up on Windows. I was once more again bitten by the fact that open on Windows defaults to being in ASCII mode.
The next thing to add was SDL input for the keyboard and mouse. And at this point googling around for an example of an input loop for SDL that is appropriate for an emulator I stumbled uppon the fact that there already was a SDL support built into the more current version of Basilisk II. But for some strange reason I kept going ahead, and incorporated some of the code into my 0.8 branch. And then I could finally send some keystrokes, move the mouse, and click on things! Things were looking up!
While looking at the SDL code, I did see they also have audio support, so I went ahead and borrowed the skeleton framework from there, although the initialization didn’t work at all as BasiliskII had drifted in how it hooked into the native sound support. So I once more again turned to SDLQuake, and I was able to initialize sound, and Even get QuickTime to play the old Quadra quicktime video, which was the first QuickTime thing I’d ever seen, back when they were still making Quadras.
So now with video and sound in place, it was finally time to tackle the networking. At first this seemed quite easy to do, and using SIMH for inspiration I was able to quickly replace the tun/tap code with some pcap code to open the interface, send packets, and receive packets. One more again I started on Linux, made it build on OS X, although my MacBook air doesn’t have anything I can really inject packets into so I don’t know if it actually works. The bigger test for me was on Windows with a GNS3 network, and with a few more minor changes I was happily sending AppleTalk to both Shoebill and Windows NT.
The next thing I wanted to tackle was SLiRP support. Ironically to bring SLiRP to Shoebill I used the SLiRP from the github of Basilisk II. At this point I figured this would be very simple, and I could wrap up later that day. It ended up taking me three days. Once more again my build would crash all the time, just like the later Basilisk II builds. Using Internet Explorer 4.0.1 would seemingly crash the whole system within seconds with faults in SLiRP’s slirp_select_fill, and slirp_select_poll functions. Now if you don’t call these functions SLiRP doesn’t process it’s TCP state and you end up with barely functioning UDP to only SLiRP which isn’t great beyond DHCP and DNS. First I tried semaphores which only made things worse as the nature of Basilisk II’s threaded nature just made the requests stack up deadlocking within seconds. I tried a mutex, timed mutexes and various other locking methods insdide of SLiRP and Basilisk II to no end. Netscape would kind of work, but IE would crash the whole thing out after a few pages. Then a better solution hit me as I was playing with the system clock on the Windows build. There is a 60Hz timer that calls a 1Hz timer once every 60 ticks. What if I had the clock drive SLiRP? And to my amazement not only did that work, but it worked great until I hit another problem that I had with Shoebill (that needs to be fixed now that I found away around it here). There is a static buffer that passes data between SLiRP’s callback when it is going to send a packet to BasiliskII and when Basilisk II then feeds the packet to MacOS. With enough traffic it will overwrite part of itself as they are on two different threads. Once more again I tried semaphores, which of course is the wrong tool here as if something is stacking waiting for it to unstack is just crazy, and more mutexes. The mutexes kind of worked but performance was horrible, as in 1992 dialup speed horrible. And I didn’t want to simulate a 1992 internet experience 100%
So the obvious solution as a queue. I took a simple queue implementation, added the ability to peek, changed it to accept a packet structure and I was set. Now I only needed a mutex when I queued items, and dequeued them. But I could hold 100 packets easily.
So with all that in place I can finally download files greater than 10MB, and even with Internet Explorer!
So the next was to make Pcap dynamically loaded, which for C++ is a bit of fun with __cdecl, GetProcAddress and all that fun. But I had it working after a bit so now if the user doesn’t have WinPcap installed they don’t get an error message, and I don’t have to maintain two builds. Nobody likes doing that kind of stuff. Ever.
There is still plenty of things broken afterall I’m using an ancient version of Basilisk to base this off of. I’ve also removed a bunch of features as I wanted to make this more of a ‘core’ product with again a focus on networking.
Will this interest the majority of people? Probably not. But for anyone who wants to actually download a file this may be somewhat useful.
Where to go from here?
Well there is still a lot of OS specific stuff in the code that I want to convert to SDL. I’d like to build from a 100% more generic code tree rather than having private files here and there. The CPU optimization programs that re-read GCC’s assembly output don’t do anything. I want to try it through an older version of GCC and see if there is any difference in speed. I also recently received the source code to vc5opti.cpp and I’d like to try that to see if it speeds up the Windows Visual C++ based build. Long term I’d love to patch in the UAE CPU code from the newer versions that have a far more solid 68030/68881 and 68040 emulation. The price of standing on so many tall shoulders is that when I fall off I don’t know if the CPU exceptions I see are faults in the CPU emulation, Basilisk II or just plain crashes in MacOS which was certainly not the most stablest thing once you mixed in multimedia and networking. It was par with Windows 3.1, which honestly both of them were ‘saved’ with help from the older generation, ala BSD Unix for MacOS, and the VMS team for Windows.
So after all this I’m ready to release some binaries, and code. Although the last thing I wanted to do is add more confusion by calling this Basillisk II v0.8.SOMETHING … A quick google search on Basilisk gave me this:
Great news! The excellent A/UX capable emulator Shoebill, now has working Ethernet support! The sad news is that it only supports the TUN/TAP interface. So Windows users are kind of left out in the fun.
Except, I’ve been here before with SIMH ages ago. So I dusted off my source code, and injected it into Shoebill. The first issue I had was that SLiRP was rejecting all the inputted frames, because of invalid frame length. Even more weird is that ARP worked, and I could see the 10.0.2.2 and 10.0.2.3 virtual IP’s but TCP and UDP outbound wouldn’t work at all.
It took me longer than it should have but although this code worked great with GCC 2.7 and 3.0, 4.x breaks it. And it’s the same reason why Shoebill originally didn’t work on Win32, the blasted packed structures! So adding the ‘-mno-ms-bitfields’ flag to GCC is all it took, and now I could ping 10.0.2.2 for about 5-7 pings until SLiRP would crash. I tried all kinds of stuff trying to see if there was an issue with SLiRP, but I should have payed closer attention to the debugger, with all those threads flying around. It turns out Shoebill was trying to read & write a the same time, which caused SLiRP to crash as it is not re-entrant. I tried to place mutex’s on every SLiRP call but that ended up having SLiRP not process any packets. Very strange. I then reduced it to where I read the frame out of SLiRP and pass it to Shoebill, and where Shoebill write’s a frame out the SLiRP. And much to my amazement I can run ‘worms’ just fine!
So after a minute of worming and pinging I called it ‘good enough’ and rebuilt a production binary, and packaged up my source code.
Well looking around on my sourceforge page, it hit me that I never did do a NetBSD 1.2 MicroVAX II package, so I thought I’d slap one together. I basically just followed my install notes, and added in some stuff that I’d built earlier.
Welcome to this minimal version of NetBSD 1.2 for the MicroVAX II.
just fire up the emulator like this:
VAX simulator V3.8-1
run.ini> set idle OLDVMS
TS: creating new file
Loading boot code from ka655x.bin
KA655-B V5.3, VMB 2.7
Performing normal system tests.
You’ll be booted up to the boot rom. next we have to boot from the
hard disk. NetBSD’s bootblocks were very fragile back then so
it won’t autoboot. I never did tear into it to see why it won’t boot
so you’ll have to do it the old fasioned way.
There is no root password, so you can just login as root, and away you
go. I prefer to telnet in so I get a working terminal as the console
doesn’t do any VT100 emulation, its more of a dumb TTY. Outside of the
default programs in NetBSD the following programs have been installed
into the image:
This should at least make using the system somewhat tollerable.
Q:When I hit backspace I get ^H ‘s!!!
A:stty erase <backspace>
In unix they used keyboards with delete keys instead of backspaces… Oh the horrors.
This should be simple, login as root and just issue the following command:
And you’ll get halted to the SIMH prompt from there you can just quit.
The new build of SIMH with SLiRP adds some performance improvements, along with the older more compatable idle code. I’ve included the source with this build so I don’t lose it again… I can’t say just how difficult it was to piece this together again from my notes, and sadly it should have been way easier. The vax/vax780/pdp11/pdp10 are already prebuilt for windows users, and I built them with MinGW… YMMV as they say.
But if you are using one of my prior BSD packages (the 4.2 or the 4.3 RENO) you’ll want to replace the vax.exe/vax780.exe’s with these ones, and alter the config so that they both have
set cpu idle=FIX
that way it’ll run faster, and take up far less cpu when idle… Right now my Quasijarus is using 5% of my laptop idling with 1 connected user.