最可怕的引导加载程序代码
The scariest boot loader code

原始链接: http://miod.online.fr/software/openbsd/stories/boot_hppa.html

1999年,一家公司退役了一台HP 9000/720工作站,最初购买用于运行HP/UX下的特定软件。它最终成为X终端的启动服务器,并因硬盘故障而苦苦挣扎。尽管系统管理员优先处理其他任务,但该机器一直存在,直到该公司更换了X终端。作者获得了该工作站,意图运行OpenBSD,移植工作主要由Michael Shalayeff推动。 OpenBSD的移植面临挑战,因为文档有限,主要依靠晦涩的MkLinux项目来获取灵感。作者原本希望做出贡献,但技能尚不足。麻省理工学院学生Matt Fredette的进步推动了项目,他利用Shalayeff的工作创建了一个NetBSD移植版本,实现了多用户功能。Fredette的工作重振了OpenBSD的开发。 一个关键的挑战是在HP 712型号上启用串行控制台访问,HP故意禁用了该功能以鼓励购买715型号。作者成功地逆向工程并实现在OpenBSD的引导加载程序中的解决方案,从而实现了无头操作——即使在晦涩的波特率下——并将代码分享回社区。这涉及在每个支持的速度下进行繁琐的测试,揭示了较低速率下令人沮丧的慢速显示,但最终确保了强大的功能。

黑客新闻 新的 | 过去的 | 评论 | 提问 | 展示 | 工作 | 提交 登录 最可怕的引导加载程序代码 (online.fr) 23 分,by todsacerdoti 4 小时前 | 隐藏 | 过去的 | 收藏 | 1 条评论 actionfromafar 56 分钟前 [–] 非常“你的工作是交付你知道能工作的代码”。回复 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请 YC | 联系 搜索:
相关文章

原文

In 1999, a company I had been working for in the past decommissioned some hardware, including an HP 9000/720 workstation, a somewhat early PA-RISC model.

In this company, we were using IBM (RS/6000), Silicon Graphics (Indigo2, Octane) and (mainly) Sun SPARC (20) and UltraSPARC (2, 30) workstations; that particular system had been bought to use a specific piece of software I don't remember the details of, which was only available under HP/UX, HP's own flavour of Unix.

After the person for which the software - and thus the machine - had been bought left the company, the machine was left in a corner in the printers room, acting as a boot server for the various X terminals in use at the company.

The HP machine used to have two 425MB SCSI internal disk drives, but one of the disks was dying, and the system would not come up multiuser without some manual interaction to bypass the failing filesystem check and let the system run in a somewhat degraded mode. But there was no intent to buy a replacement disk, and as long as the X terminals could still boot, we would happily forget about this machine until the next power outage, a rare event which would suddenly remind every X terminal user and every system administrator that this machine existed.

Don't get me wrong - this company had top notch system administrators (except for me, the junior) - but there were always more important work to do than work on this machine's replacement.

Then the company killed two birds with one stone by deciding to get rid of all its X terminals.

I had remained in good terms with enough key people there, that they told me I could drop by to say hello and get that machine if I was interested in it. Needless to say, of course I was! (and a big "thank you" to Francis C. and Jean-Marie J.)


But I was not interested in running HP/UX on it. I wanted to run OpenBSD, and after I got that machine, I started following the OpenBSD porting effort closely.

This porting effort was mostly the work of one man, the late Michael Shalayeff, who had been working on-and-off on it since 1998, slowly making progress despite the lack of documentation and only the PA-RISC port of MkLinux (a niche software project at the end of the 1990s: a cross between the Mach microkernel and the Linux operating system, which never got popular and died into oblivion after a few years) as source code inspiration.

I was supposed to help him, but the memory management bugs he was fighting at that time were way above my current skills at the time, and I couldn't really work on device drivers until the kernel was stable enough to let userland have its chance of using some processor time and exercize the drivers.

The best I could do at this point was moral support, as well as testing his work.


Early 2002, while the OpenBSD code was still not stable, MIT student Matt Fredette used it as a basis of a NetBSD port:

Date: Fri, 1 Feb 2002 11:53:40 -0500 (EST)
From: Matt Fredette
To: [email protected]
Subject: sneak preview: hp700

Hi!  At the end of September I got an HP 9000/715, and I grabbed
all of the OpenBSD/hppa code and started working on it.  Michael
Shalayeff, the OpenBSD/hppa port maintainer, has a very good
foundation of code, which has saved me months of time.  Now, after   
a lot of coding myself I'm into single-user mode.
  
This is really just a sneak preview - this entire effort is still
in its earliest stages.  The system is not stable.  Many questions
that you may have, I may not be able to answer (I'm no expert on
the architecture - but I am learning more every day.)  I don't have
anything that can be downloaded and generally used yet, on the 715
or any other machine.
  
But things are looking up...
  
Matt

After spotting and fixing the few remaining bugs which had prevented OpenBSD to run so far, his system eventually reached multiuser.

Fredette went to become a meteoritic NetBSD developer, creating two new ports (NetBSD/hp700 to the PA-RISC architecture, which became NetBSD/hppa a few years later, and NetBSD/sun2 to the Sun-2 family of Sun workstations sporting a 68010 processor and Sun's custom MMU, while the existing NetBSD ports for Motorola 68000 family processors until then were limited to 68020 and later processors; some limitations of the 68010 required enough changes and redesign for this to be a significant effort endeavour)... and disappearing from sight shortly after graduating.

He also wrote TME, ``The Machine Emulator'', an emulator for various Sun systems (Sun-2, Sun-3 and some SPARC) on which you can run the original SunOS as well as NetBSD.

Shalayeff and Fredette did not ignore each other, and this NetBSD work caused a healthy regain of activity on the OpenBSD side. Which meant more kernels to test, preferrably on as many different systems as possible.

Date: Fri, 1 Feb 2002 13:07:39 -0500 (EST)   
From: Matt Fredette
To: Michael Shalayeff
Subject: Re: sneak preview: hp700

> re
> care to share the changes back ?
> cu

Definitely.  If you want, I can give you a .tar of my sys/arch/hp700
right now, or soon I hope to start committing into the NetBSD CVS.

Matt
Date: Thu, 7 Feb 2002 11:09:01 -0500 (EST)   
From: Matt Fredette
To: Michael Shalayeff
Subject: Re: sneak preview: hp700

[...]
> just in case the idea of sharing the changes sounded
> strange, let me put my point why i think it's a good thing.
> mainly because that way we both advance faster and get
> more work done by not stepping on each others toes.
> what do you think?

I'm a big believer in sharing, absolutely.  Within the next
week I hope to start committing to NetBSD's CVS.
[...]

At that time, the most commonly encountered systems on the used workstations market were models 712 and 715, as well as less common models 720 (such as mine), 730 and 750, and their slightly less old counterparts 725, 735 and 755. But 712 and 715 were significantly more popular.

So while my 9000/720, which sported the so-called PCXS processor, wouldn't be able to run OpenBSD until 2009, when I eventually completed the necessary software support bits for that particular processor flavour, I had already gathered at that time several 9000/712 and 9000/715 systems, including a somewhat rare 9000/715/XC (100MHz processor, with 1MB L2 cache!) which used to be in use at Rolls-Royce offices in the United Kingdom, running CAD software.

The 9000/715 workstations were HP's basic workstations. Unlike the older 9000/705 and 9000/710 they were replacing, they had a larger chassis (desktop system form-factor rather than pizzabox form-factor), which allowed room for two disks and a 5"1/4 tape or CD-ROM drive, as well as an expansion slot (either proprietary SGC, for frame buffers or fancy - FDDI and ATM - network, or industry-standard EISA), while models 705 and 710 did not have any expansion capabilities and could only accomodate one disk drive and a 5"1/4 bay. So it should not be a surprise that these models were quite popular in the middle of the 1990s.

Yet the price tag of these workstations could still be a problem for smaller businesses. This led HP to start working on a stripped-down 715, which would be closer to the form factor of the 705 and 710, retaining some expansion capabilities with specific boards in a special form factor (which would be, to SGC boards, what Mini-PCI were to be to PCI, years later).

Compared to the 715, the 712 only have one internal 3"1/2 disk drive, one optional floppy disk drive, and two mini expansion slots. They were also limited in memory, with only four SIMM sockets, allowing for up to 128MB; the later "high-end" 712/100 model, with a faster processor, had six sockets, allowing for up to 192MB. (I own such a maxed out 712/100 system, courtesy of Mark Zyngier of Linux fame, and it's a really nice critter)


Of course, if you are marketing a cheaper-but-covers-99%-of-your-customers-needs workstation (the 712), chances are your customers will buy it instead of the more versatile but more expensive workstation (the 715). So HP needed a way to make the 715 more appealing than the 712 to a large enough part of the workstation market.

Now, a key feature of Unix workstations is that, if there is no keyboard plugged in on powerup, they recognize this and switch to serial console. This feature is quite helpful and allows a workstation to be turned into a cheap server by simply unplugging the keyboard (and powering the monitor down). All workstations of the 1990s behave this way, except for two shameful exceptions: the NeXT workstations (for which you need to plug a resistor in the keyboard port for them to be able to power up in the absence of a keyboard), and the Digital DECstation 5000/100 series (for no good reason, and I am tempted to believe it's actually a firmware bug, since e.g. the 5000/200 series show the expected behaviour when no keyboard is connected).

Thus some HP manager thought it was a good idea, in order to make customers prefer the 715 to the 712, to not let the 712 work without a keyboard plugged in. While you could run a 715 headless with a serial console, if you were to dare powering up a 712 without the keyboard plugged in, its firmware would complain that the keyboard is missing and freeze, refusing to boot the operating system; one had to power down, plug a keyboard, and power the machine back up for it to boot.

Except that, the 712 motherboard being roughly a stripped-down 715, there was nothing preventing it to work headless. The requirement to have a keyboard connected was built into the firmware, not in the hardware or the HP-UX operating system. And (some) HP engineers working on 712 support preferred to run their prototypes headless, in order to save desk space.


It shouldn't be surprising that the HP-UX FAQ eventually grew an entry for "how can I make a 712 run headless". It was possible, and to do it you had to change the firmware "console" path. The 712 firmware would not allow you to do this, to keep you locked to a keyboard and frame buffer console, but some of the HP-UX standalone tools could be used to change this without the firmware getting in the way, so the FAQ recipe was roughly "abort the boot sequence, at the BOOT_ADMIN> prompt, do not start the HP-UX kernel but some diagnostic tool, and then at the tools prompt, type a magic sequence without any mistake or you'll be very, very, very sorry".

There was no exaggeration in these words: the magic sequence is conspath 2/0/4.0x283, which is everything but intuitive and easy to remember.

Interestingly, while working on this story in 2025, I could not find mention of the 712 serial console in the currently available HP/UX FAQs anymore. I can only guess interest for this faded as soon as faster, PCI-capable PA-RISC systems (B-class and C-class) became easily available and affordable on the second hand market and 712 serial console no longer was a frequently asked question.

You can still find this procedure explained by HP engineer Matt Taggart:

Date: Thu, 23 Dec 1999 12:31:55 -0700
From: Matt Taggart
To: Matthew Wilcox
Cc: Bill Katz, [email protected]
Subject: Re: [parisc-linux] How to set serial console on 712 (fwd)

[...]

The above statement about serial console not being "supported" on 712 is
correct. That doesn't mean you can't do it. Here are the instructions,

-------------
CONFIGURING A RS-232 CONSOLE on a 712

An RS-232 console is not a supported feature in the 712 products. For this
reason users cannot select the RS-232 port as a console from the BOOT_ADMIN
prompt.

These instructions will configure an RS-232 console with 9600 Baud, 8 data
bits, 1 stop bit, and no parity.

HOW-TO INSTRUCTIONS

NOTE: If the following instructions are not entered correctly, your system
may be left in an un-usable state. Contact support to "dagger" your system
in this case.

     Power up the 712 system.
     Press (ESCAPE) during boot to abort auto booting the system.
     At the BOOT_ADMIN> prompt, use the boot command and the isl keyword.
        This will stop the boot sequence at ISL instead of booting to the OS.
     For example: 'boot scsi.6 isl'
     At the ISL> prompt, type 'conspath 2/0/4.0x283'
     At the ISL> prompt, type 'disp' and verify console path is:
        (hex) 2/0/4.283.0.0.0.0.0
     If necessary re-type the conspath command above.
     Connect an RS-232 terminal to the system.
     Power cycle the system to bring it up on an RS-232 console.
-------------

As it indicates above, *BE VERY CAREFUL* or you can hose your system. If you
do, I have one of the "dagger" cards that can be loaned out to fix it.

And nowadays, of course, this procedure is still documented for NetBSD.


Now, in the late 1990s and early 2000s, hobbyists buying 712 (when not getting them for free) did not care about HP choices, but wouldn't mind being able to run their systems headless. Yet they might not have an HP-UX install available, to follow the FAQ instruction and issue the arcane sequence of instructions allowing the 712 to run with a serial console.

And anyway, we OpenBSD people definitely wanted to be able to use our 712 that way, without any outside help.

We knew better. We knew we could do better. But, somehow, I hadn't realized this, yet:

Date: Wed, 6 Feb 2002 22:33:19 +0000
From: Miod Vallat
To: Michael Shalayeff
Subject: Re: console boot does not work well for me

[...]
I will have trouble switching the 712 to serial since doing so requires
a disk and the ability to "boot scsi.# isl" to enter the magic commands.
To which he simply replied:
From: Michael Shalayeff
To: Miod Vallat
Subject: Re: console boot does not work well for me

yes, it needs hpux's isl
you can hack ours to do so ? (;
(ours here, meaning the boot blocks). And then it dawned on me. Of course we could do this!
Date: Wed, 6 Feb 2002 22:43:29 +0000
From: Miod Vallat
To: Michael Shalayeff
Subject: Re: console boot does not work well for me

> yes, it needs hpux's isl
> you can hack ours to do so ? (;
Why not? I'll have to check where you pick console settings to know if
it is safe to store values from the booter...

So here I was, "challenge accepted": allow the OpenBSD boot blocks (which were extendable with machine-specific commands) to display and modify the firmware's "console path".

The HP-UX FAQ would warn that, if you were to make a mistake when setting the console path from the HP-UX diagnostic tools, you would need an HP field engineer to service your machine with a special "dagger" board, which would whack/reset/whatever the firmware settings and revert the machine to glass console, from which you could try your (un)luck a second time.

I had never seen such devices, I didn't even know if they were real or yet another Knecht Ruprecht device intended to scare users in buying 715 systems and leaving their 712 alone. (I suppose they were only created after some people at HP mistyped their commands and bricked their systems and the hardware guys got tired of having to exchange their systems or replace their eeprom chips and wanted a faster way to solve the problem)

Date: Wed, 6 Feb 2002 23:08:40 +0000
From: Miod Vallat
To: Michael Shalayeff
Subject: Re: console boot does not work well for me

> perhaps 712 would not be a good test case though (;
That's what the other machines are for, eh!

> although there are those "dagger" boards to fix 'em.
Frankly, I'd rather never have to see one of these torture devices.

So it was decided. I would work on the machine-specific command to setup the console path, test it thoroughly on 715, when recovery was possible, and only after, try in on 712.

The first part of changing things being knowing what you are working on, my first step was to collect and display the console path.

Date: Fri, 8 Feb 2002 02:18:31 +0000
From: Miod Vallat
To: Michael Shalayeff
Subject: first step at the console stuff

Well, I am going to bed.
I have a boot loader that will let you play with the console settings,
but will not save them in any way (yet).

Attached are:
- a patch to sys/arch/hppa/stand/boot/Makefile.
- sys/arch/hppa/stand/boot/machine.c

Quick dox:
display console with "machine console"
change console with "machine console port.speed.bits.parity"
where:
  port = rs232 or rs232_2
  speed = 110, 150, 300, 600, 1200, 2400, 4800, 7200 or 9600 (default 9600)
  bits = 5, 6, 7 or 8 (default 8)
  parity = even, none or odd (default 8)
You can omit the latest fields if they are the default values:
  machine console rs232_2.1200
is equivalent to
  machine console rs232_2.1200.8.none

The next day, I managed to switch my 712 to the canonical 9600 8N1 serial settings.

Date: Fri, 8 Feb 2002 21:17:11 +0000
From: Miod Vallat
To: Michael Shalayeff
Subject: 712 runs serial!

Well, I got the 712 to talk to me over serial port.
Same problem once kernel is booted.

I have to go for the week-end, will come back on sunday evening.

In the meantime, attached are:
- remaining diffs (I need strcmp in stand.h, btw)
- latest cmd_hppa.c which will update stable storage and change
  settings.

Three days later, OpenBSD/hppa was booting single-user for the first time on the 715/100/XC, which was a good milestone.

After spending a few weeks on the other platforms supported by OpenBSD, I resumed working on OpenBSD/hppa and reached a good state early march:

Date: Fri, 1 Mar 2002 02:10:37 +0000
From: Miod Vallat
To: Michael Shalayeff
Subject: cmd_hppa.c, updated

Ok, here is the current status.

The detection and assignment of keyboard and serial paths works well
here, on the following machines:
- 720 (2 serial ports on the same bus, hil, asp)
- 712/60 (1 serial port, ps2, lasi)
- 715/33 (2 serial ports on the same bus, hil, asp)
- 715/100/XC (2 serial ports on two different bus, hil, ps2, lasi)

I am not very satisfied with the graphics path code. It happens to work
for me, but it's too much a wild guess - except to switch to the default
(first card) graphics path.

Comments, ideas, improvements?

The day after, I ended up being satisfied with my work.

Date: Fri, 1 Mar 2002 23:04:52 +0000
From: Miod Vallat
To: Michael Shalayeff
Subject: hppa console stuff, revisited

Well, I think this version is safe and reliable enough to go into the
tree, and there is its man page as well.

It will let you switch back and forth between various graphics and
serial consoles without disturbing the PDC settings, while the previous
version did not. It will also correctly identify GIO-attached devices as
the main devices (the previous version did not order the framebuffers of
my 715/100XC correctly).

The only problem left is still the graphics console resolution. The code
will read it correctly in the console path, will write valid values back
in it, but that's not enough, and the resolution will reset to the
default one (i.e. graphics_#.1). I suppose this information is also
stored elsewhere, and the other area where it is stored has higher
priority in the PDC code.

I plan to investigate this problem soon, but in the meantime this is not
a too big problem, since you can set the console path from the pdc
itself. That's switching from and to serial console mode which matters,
in the 712 point of view at least.

The manual page could be a bit more verbose, but I think it's a decent
start. Heavily inspired from the i386 version.

I choose to left the "set tty" information commented out, since I doubt
it would work in hppa land currently.



Comments? Rants? Clear to commit?

This work eventually got commited on march 2nd, with further improvements on march 7th.

Of course, I had to eventually document this in the boot loader as well as the machine-specific boot process details manual pages once the first working OpenBSD/hppa release was getting ready.

Date: Thu, 17 Oct 2002 21:49:58 +0000
From: Miod Vallat
To: Michael Shalayeff, Todd Fries
Subject: boot_hppa(8)

There are lots of repeated texts, but I think this will be useful
enough.

This definitely does not pretend to document all PDC usage, but should
be enough for people to be able to boot the way they want.

Note that I don't plan to commit this until I am done with the others
boot_foo.8 cleaning, unless mickey pressures me.

Comments?

Now, you might remember the special command from the FAQ using 0x283. This number is an encoding of the speed, number of data bits, number of stop bits, and parity.

Contrary to what I wrote in the first email on february 8th, there are more speeds than 110 to 9600. The HP workstation firmware supports all these speeds: 50, 75, 110, 150, 300, 600, 1200, 2400, 4800, 7200, 9600, 19200, 38400, 57600, 115200 and 230400 bits per second.

Before I were to release my code to the general public, I needed to test all these speeds. This is where the horror story starts. The machine I was testing against (i.e. the other side of the serial link) was a Sun SPARCstation 20, which serial ports can't go faster than 38400 bits per second. Because of this, I did not test the three fastest speeds (I would have been able to test 57600 on a PC, but nothing faster). Shame on me.

But I tested all the other speeds, from 38400 down to 50.

So every test went this way:

  • power cycle the machine to make the firmware use the newly configured settings.
  • wait about 10 seconds for it to perform its self test (including the memory check) and start using the serial console.
  • wait for the boot messages to appear:
    
    
    ----------------------------------------------------------------------------
    BootRom Version    1.1  
    Memory Size:  128 MB
    ----------------------------------------------------------------------------
    
    
    
    
    (c) Copyright 1990-1994, Hewlett-Packard Company.
    All rights reserved
    
    Press <ESCAPE> to stop boot sequence.
    
    Starting Auto boot
    
    
    Loading Initial Program Loader
    
    
    IPL successfully loaded
    
    
    Booting
    
    
    >> OpenBSD/hppa BOOT 0.7
    booting dk0a:/bsd
    
  • too many times, realize I did not pay attention to abort the boot process, and reboot once OpenBSD has completed booting.
  • on the next boot, press escape like mad to abort the boot process in time and get the boot administration menu:
    ----------------------------------------------------------------------------
    Command                                Description
    -------                                -----------
    Auto [boot|search] [on|off]            Set/show auto mode
    Boot [pri|alt [isl]]                   Boot from primary or alternate path
    Boot [scsi|eisa.<slot>[.<addr>]] [isl] Boot from SCSI or EISA
    Boot lan[.<addr>] [install] [isl]      Boot from LAN
    Chassis [on|off]                       Set/show chassis codes display mode
    DefaultSS                              Reboot and set EEPROM to default values
    Diagnostic [on|off]                    Set/show diagnostic boot mode
    Fastboot [on|off]                      Set/show fast boot mode
    Help                                   Show this command menu
    Information                            Show system information
    LanAddress                             Show LAN station addresses
    Monitor [<DEV>[.<type>]]               Set/show graphics monitor type
                                           (<DEV>=graphics|graphics_<1|2>)
    Path [pri|alt [<DEV>[.<addr>]]]        Set/show boot source path
                                           (<DEV>=lan|scsi|eisa.<slot>)
    Path [console [<DEV>[.<parm>]]]        Set/show boot console path
                                           (<DEV>=<RS232>|<GRAPH>
                                            <RS232>=rs232|rs232_2
                                            <parm>=<baud>.<length>.<parity>
                                            <GRAPH>=graphics|graphics_<1|2>
                                            <parm>=<monitor>)
    Path [keyboard [hil|ps2]]              Set/show boot keyboard path
    Pim [hpmc|toc|lpmc]                    Show PIM info
    Search [ipl] [scsi|eisa]               Show potential boot devices
    Search [ipl] [lan [install]]           Show potential boot LAN devices
    Secure [on|off]                        Set/show security mode
    ----------------------------------------------------------------------------
    BOOT_ADMIN> 
    
  • ask for an interactive boot...
    BOOT_ADMIN> boot pri isl
    
    
    
    
    Attempting to boot.
    
    Loading Initial Program Loader
    
    
    IPL successfully loaded
    
    
    Booting
    
    
    >> OpenBSD/hppa BOOT 0.7
    boot> 
    
  • ...at which point I could check the current setting, and switch to the next (slower) speed in the list:
    boot> machine console
    Console path: rs232.9600.8.none
    boot> machine console rs232.4800
    you will need to power-cycle your machine for the changes to take effect.
    Console path: rs232.4800.8.none
    boot>
    

At first glance, there is nothing odd with this. It's only a tedious process which will need to be repeated 13 times, from 38400 bps to 50.

But the help text before the BOOT_ADMIN> prompt alone is 1967 bytes long.

On a canonical 9600 8N1 setup (9600 bps, 8 data bits, 1 stop bits, no parity), each visible byte needs to transmit 9 bits (due to the stop bit), so 1967 bytes account for 17703 bits, which, at 9600 bps, take 1.844 second to display. That doesn't feel slow.

But as soon as you start hitting the low speeds, that wall of text takes more and more time to appear. At 1200 bps, it now takes 8 times longer, 14,75 seconds to display. And after 1200 bps, there are still 6 slower speeds to try: 600, 300, 150, 115, 75 and 50 bps.

It would be cliché to tell you that you have enough time to see your life flashing before your eyes while waiting for this display to complete, yet at the slowest possible speed of 50bps, it takes a bit short of 6 minutes for it to appear in its entirety. And that's only one step of the process...

So what seemed to be a simple "ok, let's try all the available speeds" turned out to last two good hours, and I really was relieved once completed and all tested speeds had worked. But hey! That's the only way to really trust that code. (I had also tested the various number of data and stop bits, as well as the parity settings, at 9600 bps)


And while the HP/UX (or nowadays NetBSD) FAQ only lets you use 9600 bps because of that 0x283 value, if you run OpenBSD (or simply boot its installer once to perform that configuration change), you can run your 712 headless at 57600 bps. And be the coolest kid of the block.

联系我们 contact @ memedata.com