Author Archives: Michael Kuron

Sipura SPA-3000 spontaneous reboots, reason 0x737208f4

I have a 10-year-old Sipura SPA-3000 VoIP phone adapter (SIP to FXS phone) which at some point started rebooting once an hour, even during calls. After enabling remote syslog, I saw that these reboots happen with no prior indication, and after the reboot, I see the following message:

Jun 16 21:15:16 192.0.2.2 logger: <134>System started: ip@192.168.0.101, reboot reason:H737208f4
Jun 16 21:15:16 192.0.2.2 logger: <134>System started: ip@192.168.0.101, reboot reason:H737208f4

These hexadecimal reboot reasons don’t appear to be documented anywhere, the only list I could find appears to refer newer models and doesn’t contain 0x737208f4.

After some trying, I figured out that if I disable DHCP, the reboots don’t happen anymore. My DHCP always assigned the same IP to the device, so I really see no reason why it would have to reboot.

 

CUPS-to-CUPS printing with server-side processing and page_log

Printer sharing on Windows is easy: the client receives the driver from the server, presents the driver GUI and passes on an intermediate format along with the options selected in the driver to the server, which then renders the print job for the printer (usually into PostScript).

In the Unix (Mac OS X in my case, but Linux would be the same) world, CUPS is commonly used for printing. It’s very powerful, but I find the documentation severely lacks details about the exact way something is implemented in the code. Luckily, the code is open-source and Michael Sweet, the developer of CUPS who now works at Apple and still maintains CUPS, managed to create a very structured piece of software with code that’s reasonably easy to understand.

If you just add a CUPS server’s print queue as a new printer on a CUPS client, it will work fine, but you might run into some inconveniences:

Problems

  1. The job might get run through a vendor-supplied filter twice, once on the server and once on the client. This usually works fine, but the print job might significantly increase in size (observed on an HP LaserJet).

  2. The page_log on the server might not contain the number of pages and copies a job consisted of and list 1 for both instead.

  3. The page_log on the server might not contain things like page format, duplex status or attributes you manually added to PrintLogFormat.

Reasons

  1. This happens if the PPD both on the client and on the server contains a line starting with *cupsFilter, which links to a vendor-supplied filter. Such a filter usually produces a MIME type of application/postscript.

  2. This happens if the job does not get run through the pstops filter by CUPS. CUPS bypasses that filter if the client submits the job with a MIME type of application/vnd.cups-postscript, i.e. it was already run through pstops on the client.

  3. This is either caused by the same things as (1) or (2), but I’m not sure which one.

Solution

Simply add the following lines to the PPD on the client. That way, it passes the job straight to the server for server-side processing.

*cupsFilter: "application/pdf 0 -"
*cupsFilter: "image/* 0 -"
*cupsFilter: "application/postscript 0 -"
*cupsFilter: "application/vnd.cups-postscript 0 -"
*cupsFilter: "application/vnd.cups-command 0 -"

By the way, if you use Mac OS X and let the “Add Printer” wizard automatically add a print queue from a remote CUPS server discovered via Bonjour, this is exactly what it does.

Notes

If you append something like %{SelectColor} to your PageLogFormat because that’s the attribute your printer uses to determine whether it should print in color or grayscale and you’d like to log that, please note that the default value (either as specified by the PPD or as specified by you via lpadmin -d printername -d SelectColor=Grayscale or via the CUPS web interface’s “Set Printer Defaults”) will never be written to the page_log. Only deviations from the default value will be logged. The defaults set on the server-side CUPS do not matter here, this is determined by the client-side CUPS.

Per the filter(7) documentation (italic comments were added by me):

Options passed on the command-line typically do not include the default choices the printer’s PPD file. […] use the ppdMarkDefaults [which sets all options to the defaults specified inside the PPD] and cupsMarkOptions [which sets the options to the values specified in the driver GUI] functions in the CUPS library to use the correct mapping, and ppdFindMarkedChoice [which reads from the options array composed from the defaults and the selected options] to get the user-selected choice.

WordPress Plugins

After I recently set up a blog for a friend, I thought I’d post a list of plugins I use on the various WordPress instances I run for various people and myself.

  • Simple Custom CSS. Allows you to add custom CSS to your blog without having to modify theme files. This makes it easy to update themes in the future without breaking your customizations.
  • Include plus Shortcodes Everywhere. This allows you to create a Text Widget that displays a static page from your blog using a tag like [include id="15"].
  • Category Order. Allows you to reorder the list of categories in the sidebar.
  • KB Easy PicasaWeb. Converts Picasa links into embedded photo galleries.
  • WP Events Calendar. Gives you a simple calendar widget into which you can manually enter events.
  • Jetpack. Enables some useful features like infinite scrolling, custom CSS, sharing links, and mobile theme.
  • Akismet. A must-have spam filter if you allow comments on your blog.
  • Contact Form 7 plus Really Simple CAPTCHA. Highly flexible contact form including CAPTCHAs.
  • WP Permalauts. A must-have if you blog in a language that has accented letters or umlauts. It converts those letters to the non-accented ones in permalinks.
  • WP Hide Post. Lets you selectively hide posts from categories, front page, etc. while they remain accessible through other ways and direct links.
  • BackWPup. Does full backups of your WordPress data and database to a tarball on the server or your Dropbox. Can run on a schedule to automate the backups.

A theme that I quite like is Sunspot. You can display the featured image, title and lead text of two posts next to each other and customize how many posts you want per page in total. It also has enough space for widgets in its sidebars and is responsive. The downloadable version does not currently do infinite scrolling, but I believe hosted WordPress.com has such a version.

Calling the parent constructor in PHP 5

Say you write a PHP class that needs to call the parent constructor. At first sight, this is simple:
function __construct()
{
parent::__construct();
}

Say you want to pass some arguments to the parent constructor:
function __construct($arg1, $arg2)
{
parent::__construct($arg1, $arg2);
}

Now what do you do if you have default arguments?
function __construct($arg1 = NULL, $arg2 = NULL)
{
if ($arg1 == NULL && $arg2 == NULL) parent::__construct();
elseif ($arg2 == NULL) parent::__construct($arg1);
else parent::__construct($arg1, $arg2);
}

Not pretty, especially if you have many possible arguments. The obvious generalization would be
function __construct()
{
call_user_func_array(array('parent','__construct'), func_get_args());
}

However, this actually fails for two reasons on PHP below version 5.3: func_get_args() cannot be used as a function argument, and call_user_func_array does not treat parent correctly.
So here’s the entire constructor I ended up with that does absolutely nothing but calling the parent function:
function __construct()
{
$args = func_get_args();
if (version_compare(PHP_VERSION, '5.3.0') >= 0)
{
call_user_func_array(array('parent','__construct'), $args);
}
else
{
$refl = new ReflectionObject($this);
$method = $refl->getParentClass()->getConstructor();
$method->invokeArgs($this, $args);
}
}

Seriously, you have to use reflections for this seemingly simple task?!

VMware ESXi 5.5.0 panics when using Intel AMT VNC

For compatibility with a new guest OS, I upgraded my ESXi  to 5.5 today. During reboot, it crashes after a few seconds (it briefly flashes a message about starting up PCI passthrough on the yellow ESXi boot screen). The purple screen of death (PSOD) I get looks like this:

VMware ESXi 5.5.0 [Releasebuild-1474528 x86_64]
#PF Exception 14 in world 32797:helper1-2 IP 0x4180046f7319 addr 0x410818781760
PTEs:0x10011e023;0x1080d7063;0x0;
cr0=0x8001003d cr2=0x410818781760 cr3=0xb6cd0000 cr4=0x216c
frame=0x41238075dd60 ip=0x4180046f7319 err=0 rflags=0x10206
rax=0x410818781760 rbx=0x41238075deb0 rcx=0x0
rdx=0x0 rbp=0x41238075de50 rsi=0x41238075deb0
rdi=0x1878176 r8=0x0 r9=0x2
r10=0x417fc47b9528 r11=0x41238075df10 r12=0x1878176
r13=0x1878176000 r14=0x41089f07a400 r15=0x6
*PCPU2:32797/heler1-2
PCPU  0: SSSHS
Code start: 0x418004600000 VMK uptime: 0:00:00:05.201
0x41238075de50:[0x4180046f7319]BackMap_Lookup@vmkernel#nover+0x35 stack: 0xffffffff00000000
0x41238075df00:[0x418004669483]IOMMUDoReportFault@vmkernel#nover+0x133 stack: 0x60000010
0x41238075df30:[0x418004669667]IOMMUProcessFaults@vmkernel#nover+0x1f stack:0x0
0x41238075dfd0:[0x418004660f8a]helpFunc@vmkernel#nover+0x6b6 stack: 0x0
0x41238075dff0:[0x418004853372]CpuSched_StartWorld@vmkernel#nover+0xf1 stack:0x0
base fs=0x0 gs=0x418040800000 Kgs=0x0

When rebooting the machine now, it reverts to my previous version, ESXi 5.1-914609.

A bit of playing around revealed: This only happens if I am connected to the Intel AMT VNC server. If I connect after ESXi has booted up, it crashes a fraction of a second after I connect to VNC. Go figure! Apparently it’s not such a good idea to have a VNC server inside the GPU, Intel…

Before I figured this out, I booted up the old ESXi 5.1.0-914609 and even upgraded it to ESXi 5.1.0-1483097.  Looking at dmesg revealed loads of weird errors while connected to the VNC server:

2014-02-13T11:23:15.145Z cpu0:3980)WARNING: IOMMUIntel: 2351: IOMMU Unit #0: R/W=R, Device 00:02.0 Faulting addr = 0x3f9bd6a000 Fault Reason = 0x0c -> Reserved fields set in PTE actively set for Read or Write.
2014-02-13T11:23:15.145Z cpu0:3980)WARNING: IOMMUIntel: 2371: IOMMU context entry dump for 00:02.0 Ctx-Hi = 0x101 Ctx-Lo = 0x10d681003

lspci | grep ’00:02.0 ‘ shows that this is the integrated Intel GPU (which I’m obviously not doing PCI Passthrough on).

So

  • ESXi 5.5 panics when using Intel AMT VNC
  • ESXi 5.1 handles Intel AMT VNC semi-gracefully and only spams the kernel log with dozens of messages per second
  • ESXi 5.0 worked fine (if I remember correctly)

I have no idea what VMware is doing there. From all I can tell, out-of-band management like Intel AMT should be completely invisible to the OS.

Note that this is on a Sandy Bridge generation machine with an Intel C206 chipset and a Xeon E3-1225. The Q67 chipset is almost identical to the C206, so I expect it to occur there as well. Newer chipsets hopefully behave better, perhaps even newer firmware versions help.

Update November 2014: I just upgraded to the latest version, ESXi 5.5u2-2143827, and it’s working again. I still get the dmesg spam, but the PSODs are gone. These are the kernel messages I’m seeing now while connected via Intel AMT VNC:

2014-11-29T11:17:25.516Z cpu0:32796)WARNING: IOMMUIntel: 2493: IOMMU context entry dump for 0000:00:02.0 Ctx-Hi = 0x101 Ctx-Lo = 0x10ec22001
2014-11-29T11:17:25.516Z cpu0:32796)WARNING: IOMMU: 1652: IOMMU Fault detected for 0000:00:02.0 (unnamed) IOaddr: 0x5dc5aa000 Mask: 0xc Domain: 0x41089f1eb400
2014-11-29T11:17:25.516Z cpu0:32796)WARNING: IOMMUIntel: 2436:  DMAR Fault IOMMU Unit #0: R/W=R, Device 0000:00:02.0 Faulting addr = 0x5dc5aa000 Fault Reason = 0x0c -> Reserved fields set in PTE actively set for Read or Write.

So basically, Intel AMT VNC is now usable again.

Update August 2015: ESXi 6.0 still spams the logs, no change over ESXi 5.5.

Leserbrief “Rentenpaket”

Am 29. Januar 2014 beschloss die Bundesregierung die als “Rentenpaket” bekannte Rentenerhöhung. Unmittelbar darauf präsentierte Arbeitsministerin Andrea Nahles eine Werbekampagne dafür; über die am 30. Januar 2014 in der Süddeutschen Zeitung abgedruckte Werbeanzeige ärgerte ich mich so, dass ich einen Leserbrief zu dem Thema verfasste. Dieser wurde am 06. Februar 2014 abgedruckt:

Nachhaltige Politik ist das nicht 

Die Vorgehensweise der Bundesregierung, einen Tag nach dem Kabinettsbeschluss bereits eine Werbekampagne für das Vorhaben zu starten, ist schockierend. Hier wird das Parlament missachtet, das über die Gesetzesvorlage überhaupt erst noch zu befinden hat, und dem Bürger suggeriert, das Rentenpaket sei bereits beschlossene Sache. Ungeklärte Fragen werden einfach beiseitegewischt. Viel schwerer wiegt jedoch, dass der Bürger mit dieser Kampagne gezielt desinformiert wird und ihm eine komfortable Rente versprochen wird, ohne ihn über die massiven finanziellen und gesellschaftlichen Kosten zu informieren. Deren Großteil werden diejenigen tragen, die heute unter dreißig sind oder erst noch geboren werden; ebendie, die aus der gesetzlichen Rentenversicherung eine negative Rendite erzielen werden. Eine langfristige Umstellung vom Umlage- auf das Kapitaldeckungsverfahren wurde in den jüngsten Rentenreformen nicht einmal angedacht. Nachhaltige Politik sieht anders aus, aber an fehlende Nachhaltigkeit werden wir uns angesichts des zunehmenden Durchschnittsalters der Wähler gewöhnen müssen.

Michael Kuron, Frickenhausen 

Inzwischen ist auch bekannt, dass diese Werbekampagne über eine Million Euro kostet. In dem verlinkten Artikel zitiert die SZ u.a. M. Kurth von den Grünen mit “Dieses Vorgehen ist beispiellos […]”, was ich in meinem Leserbrief ebenfalls geschrieben hatte (wenngleich es der redaktionellen Kürzung zum Opfer gefallen ist). Ebenso beklagt der Artikel, dass www.rentenpaket.de kein Wort über die Kosten verliert.

CUPS on OS X hangs after a few days, reports “Internal Server Error”

If you set up CUPS on an OS X Server (version 10.8.5 in my case, but anything from 10.7 (where CUPS introduced sandboxing) through 10.9 (the current version) should exhibit this behavior), i.e. you enable Printer Sharing in System Preferences and run sudo cupsctl WebInterface=yes, and leave the system running for a few days, you’ll eventually run into the situation that http://localhost:631/printers will report “Internal Server Error”, and clients will no longer be able to print to the server.

Digging around CUPS’ debug log, you’ll see something like
D [27/Oct/2013:13:33:52 +0100] [CGI] sandbox_init failed: /private/tmp/05d735269fa67: No such file or directory (No such file or directory)
D [27/Oct/2013:13:33:52 +0100] PID 78980 (/usr/libexec/cups/cgi-bin/printers.cgi) stopped with status 1.

That missing file (named a different 13-digit hexadecimal name upon each restart) is the CUPS daemon’s sandbox profile.

Digging around further reveals that /var/log/daily.out contains exactly this file name:
Sun Oct 27 03:15:01 CET 2013
Removing old temporary files:
/tmp/05d735269fa67
[...]

All we need to do to prevent this from happening in the future is opening /etc/periodic/daily/110.clean-tmps in your favorite text editor and adding the line printed in bold:
set -f noglob
args="-atime +$daily_clean_tmps_days -mtime +$daily_clean_tmps_days"
args="${args} -ctime +$daily_clean_tmps_days"
args="${args} ! -group _lp ! -user _lp"
dargs="-empty -mtime +$daily_clean_tmps_days"
dargs="${dargs} ! -name .vfs_rsrc_streams_*"

Update February 2014: CUPS 1.7.1 is supposed to fix that issue; the release notes mention my reported bug. Now lets see how long it takes until Apple ships the updated CUPS with an OS X update.

Update March 2014: I just upgraded our server to OS X 10.9.2 and got CUPS 1.7.1 with it. Hooray, less than three months between bug reported and fix deployed. The sandbox profile now gets written to /var/spool/cups/tmp. In fact, that’s exactly what was changed in scheduler/conf.c in the CUPS source code: they added setenv("TMPDIR", TempDir, 1);

SSDs with TCG Opal or IEEE-1667 support

Recently, a few SSD models have been introduced that support Full-Disk Encryption per the TCG Opal standard. Many older SSDs already support AES encryption and use the ATA password for this, which is settable in the BIOS. The advantage of Opal is that it divides the drive into a small read-only segment (technically not a partition) with a special boot loader (which prompts you for the encryption password and passes it to the drive) and the encrypted segment which contains your traditional OS and data partitions. These special boot loaders can do much more than a BIOS: for example, they can provide means for key reset and they can talk to a server on the network. They can also have multiple passwords for multiple users and they can be configured entirely from within the OS, which also allows for central management in enterprise environments.

The downside of course is that you need a piece of software to use Opal. This includes WinMagic SecureDoc (for Windows and Mac), Wave Systems Embassy Security Center (for Windows only) and several others, but also BitLocker/eDrive in Windows 8 (however, this requires IEEE-1667 support as well). This is also an advantage as it does not require hardware or OS support; so even Macs could use them:

WinMagic SecureDoc already supports supported Macs until October 2013, but a version for OS X 10.9 was never released. Secude has announced FinallySecure Enterprise Full Disk Encryption with support for OS X and Opal; it hasn’t been released yet and was recently sold to a company named EgoSecure.

Probably the first drive to support Opal was the Seagate Momentus FDE, which was a spinning disk. Toshiba, Hitachi and a few others also made HDDs with Opal support.

Later, the Samsung PM830 (but not the Samsung SSD 830) and the Micron C400 SED (but not the Micron C400 or the Crucial m4) came, which were only available to OEM.

The first Opal-compliant mass-market SSD was the Crucial M500 (it’s also OEM’d as Micron M500), which is also IEEE-1667 compliant. As the M500 currently offers the best GB/$ ratio of all SSDs on the market, it’s been selling superb in the five months it’s been on the market and I hope this drives more software companies to support Opal.

The just-announced Intel SSD Pro 1500 will also support Opal, but apparently not IEEE-1667.

As far as I know, these really are all TCG Opal drives on the market, currently and previously. I expect there will be more coming, but I am kind of surprised that it took this long.

If you know of any others, let me know in the comments.

Update Dec 2013: The Samsung 840 EVO also does Opal.

Update Jan 2014: Wave Systems has a list of Opal drives that work with their software. It lists some Adata XPG SX900 models, the Kingston KC300 (only certain part numbers) and some LiteOn models.

Update Mar 2014: The just-announced Crucial M550, which is very similar to the popular M500, still supports Opal 2.0 and IEEE-1667, and is explicitly advertised as Microsoft eDrive compatible. Same goes for the almost identical ADATA SP920.

Update May 2014: The SanDisk X300s also has both and includes a license for Wave Embassy in case your computer does not support eDrive. Glad to see that Opal and IEEE-1667 are finally making it into a significant proportion of new midrange mass-market SSD models.

Update June 2014: The Crucial MX100 is similar to the M550 with cheaper NAND and supports the same encryption standards. The ADATA Premier SP610 is supposed to get Opal 2.0 through a firmware update later this year, but not IEEE-1667.

Update July 2014: The Samsung SSD 850 Pro has TCG Opal and IEEE-1667. The Intel SSD Pro 2500 has TCG Opal 2.0 and IEEE-1667.

Update September 2014: The Crucial M600 has Opal 2.0 and IEEE-1667, just like its predecessors M500, M510, MX100, M550.

Update October 2014: The Adata SR1010 has Opal 2.0 and IEEE-1667.

Update December 2014: Samsung SSD 850 EVO has Opal 2.0 and IEEE-1667.

Update January 2015: The Crucial MX 200, which is quite similar to the MX 100, has Opal 2.0 and IEEE-1667. The BX 100 does NOT have encryption and is based on a different controller.

Update October 2015: The Samsung SSD 950 Pro is supposed to get Opal and IEEE-1667 with a firmware update at some point.

Update January 2016: The SanDisk X400 is supposed to get a firmware update for Opal in April.

Update February 2016: The Samsung SSD 750 EVO, apparently intended to replace the 850 EVO, has Opal and IEEE-1667.

Update April 2016: The Crucial MX 300 does TCG Opal 2.0, IEEE-1667 and thus also Microsoft eDrive.

Update June 2016: The Micron SSD 1100 was announced with TCG Opal 2.0 and eDrive support.

PXE-booting Knoppix 7.2

I have a PXE server on my network so I can easily boot Linux live images and tools when fixing computers. Knoppix 7.2 however is unable to load a network driver on most PCs (it only works with Intel E1000 NICs) after following the standard procedure:

  1. Copy the DVD image’s contents to an NFS server
  2. Boot the DVD
  3. sudo knoppix-terminalserver, follow the assistant and select all network drivers
  4. Copy the contents of /tftpboot to your PXE server and add something like this to your pxelinux config:
    DEFAULT knoppix
     TIMEOUT 2
     PROMPT 2
    
     LABEL knoppix
     MENU LABEL Knoppix 7.2
     kernel knoppix72/boot/pxelinux/linux
     append nfsdir=192.168.200.25:/data/shares/tftpboot/knoppix72 nodhcp lang=de ramdisk_size=100000 init=/etc/init apm=power-off nomce loglevel=1 initrd=knoppix72/boot/pxelinux/miniroot.gz libata.force=noncq tz=localtime lang=de apm=power-off nomce libata.force=noncq hpsa.hpsa_allow_any=1 loglevel=1 BOOT_IMAGE=knoppix

To fix the network driver issue, apply the following diff before running sudo knoppix-terminalserver:

--- /KNOPPIX/usr/sbin/knoppix-terminalserver 2013-02-12 04:21:16.000000000 +0000
 +++ /usr/sbin/knoppix-terminalserver 2013-09-30 18:52:16.055233746 +0000
 @@ -281,8 +281,7 @@
 mkdir -p "${MINIROOT}/static"

 # Check if we need the Kernel 2.6 insmod
 -INSMOD=""
 -case "$KERNEL" in 2.6.*) INSMOD=/sbin/insmod ;; esac
 +INSMOD=/sbin/insmod

 # Unfortunately, these are not integrated in ash-knoppix yet, so we need some shared
 # libs. :-(
 @@ -326,6 +325,7 @@
 for i in $MODULES; do
 awk -F: '{if($1~/'"$i"'/) {print $2}}' /lib/modules/$KERNEL/modules.dep
 done | sort | uniq | while read module relax; do [ -n "$module" ] && cp /lib/modules/$KERNEL/"$module" "${MINIROOT}/modules/net/00_${module##*/}"; done
 +cp /lib/modules/$KERNEL/kernel/drivers/pps/pps_core.ko "${MINIROOT}/modules/net/00_0_pps_core.ko"

 #umount "${MINIROOT}"
 #dd if="$RAMDISK" bs=${MINISIZE}k count=1 | gzip -9v > "${MINIROOT}.gz"

Using Serva with an existing PXE server

A long time ago, I set up a PXE server on my network from which I can boot all kinds of Linux tools. It uses the PXELinux boot loader to provide a menu etc. When I came across an article on how to PXE boot a Windows 7 installer using Serva, I looked for a way to integrate that into my existing PXELinux configuration.

Serva takes a Windows installer CD, patches a few files, injects a small tool into the WIM, and fires up a TFTP server and DHCP proxy. It also supports Microsoft’s BINL protocol, which lets the boot loader find out which one of boot menu entries was chosen.

I went to my Linux server and created a folder named Serva in /srv/tftp and Samba shared that. I then mapped it to Z: on a Windows machine, fired up Serva, pointed it at Z: as its TFTP root and checked the TFTP, proxyDHCP and BINL check boxes. After copying the contents of the Windows 7 ISO to a subfolder of /srv/tftp/Serva/WIA_WDS and restarting Serva, the Windows side of it all was done already.

Next, I upgraded my PXELinux to version 6.0.1 and put the following files into my tftp folder: ldlinux.c32 libcom32.c32 libutil.c32 memdisk  menu.c32 netbootme.0 pxechn.c32 pxelinux.0. Then I added the following entry to my pxelinux.cfg/default:

LABEL win7-32-de-install
MENU LABEL Windows 7 i386 DE Installer
KERNEL pxechn.c32
APPEND Serva\WIA_WDS\W7_32_DE\_SERVA_\pxeboot.0 -p Serva\WIA_WDS\W7_32_DE -o 252.s=Serva\WIA_WDS\W7_32_DE\_SERVA_\boot\bcd

-p sets the PXE root path to the install ISO root and -o 252.s sets DHCP option 252 to the full path to the BCD (making all the BINL stuff unnecessary). Two more symlinks and we’re all set:

cd /srv/tftp
ln -s Serva/WIA_WDS .
cd WIA_WDS/W7_32_DE/_SERVA_
ln -s pxeboot.n12 pxeboot.0

Now the only issue that I still have is that the network share path still contains the name of the computer that originally ran Serva. This can be fixed in the BCD using a hex editor.