Table of Contents
MILO
MILO, the Alpha Linux Miniloader, is a boot loader and minimal firmware for Alpha systems. It initializes the machine, loads Linux, and provides the PALcode that Linux runs on. 1) It is used on systems with the ARC or AlphaBIOS firmware, whose PALcode is designed for Windows NT and cannot run Linux. 2) Systems with the SRM console boot Linux with aboot instead, which is simpler. 3)
MILO is therefore needed only on systems without an SRM console. The Alpha XL, the Alpha XLT, and the AlphaPC 164UX (Ruffian) can boot Linux only with MILO, 4) as can the AlphaPC 164RX, for which no SRM console was released. 5) Current kernels require an EV56 (21164A) or later processor, which rules out the Alpha XL 233, 266, and 300; the XL 366 and 433 have 21164A processors. 6) MILO does not support multiprocessor systems or 21264 systems. 7) 8)
MILO's last release, 2.2-18, dates from July 2001 and is based on Linux 2.2. 9) It cannot boot kernels from Linux 2.6.23 on, which have a PT_NOTE program header. The source repository, https://github.com/alphalinux/milo, fixed this in 2026, so a current kernel needs a MILO built from it. 10) No current kernel has been reported booting through MILO, with a repository build or otherwise.
MILO reads the kernel from ext2 (or ext3, read as ext2), and from FAT, ISO 9660, or ReiserFS if built with them, but not from ext4 or XFS; see Known issues. An initrd must fit below MILO in the first 13 MiB of memory, and cannot be used at all with a kernel built without CONFIG_ALPHA_LEGACY_START_ADDRESS; see initrd. The simplest kernel for MILO therefore has the drivers for its root file system built in and no initrd.
System support
The MILO image for each system is: 11)
| System | Code name | MILO image |
|---|---|---|
| AlphaStation 600, AlphaStation 500, Alpha XL 300/366/433 | Alcor, XLT | xlt-alcor |
| AlphaStation 200, 205, 250, 255, 300, 400 | Avanti | avanti |
| Alpha XL 233/266 | XL | xl |
| Digital Personal Workstation | Miata | miata |
| AXPpci33, Multia | Noname, UDB | udb-noname |
| AlphaPC 64 | Cabriolet | cabrio |
| AlphaPC 164 | PC164 | pc164 |
| AlphaPC 164LX | LX164 | lx164 |
| AlphaPC 164SX | SX164 | sx164 |
| EB164 | EB164 | eb164 |
| EB64+ | EB64+ | eb64p |
| EB66+ | EB66+ | eb66p |
| EB66 | EB66 | eb66 |
| AlphaPC 164UX, 164BX | Ruffian | ruffian 12) 13) |
The Noname, EB64+, EB66 and EB66+, Cabriolet, Alcor, AlphaStation 500, PC164, LX164, SX164, and Miata can boot Linux either with MILO or from SRM. 14) Digital listed no MILO image for the Jensen, the AlphaServer 1000, 1000A, 1200, 2000, 2100, 4000, and 4100, or the AlphaBook 1, all of which have SRM. 15)
- Ruffian: the Deskstation AlphaPC 164UX and BX use ARCSBIOS, which loads MILO with
ldmilo.exeinstead oflinload.exe. 16)ldmilowas written by Deskstation, and requires the MILO file to be namedmilo. 17) Digital's images for it wereldmilo-ruffian-981020andmilo-ruffian-981020. 18) - Other systems: MILO 2.2 can also be built for the AlphaBook 1, Mikasa, Takara, and Platform 2000. 19)
Obtaining and installing MILO
MILO must be built from the repository for the system's platform (see Building), since no released binary can boot a current kernel. The loader that ARC or AlphaBIOS runs to start MILO, linload.exe, was only ever distributed as a binary, 24) and the Ruffian's ldmilo.exe came from Deskstation. 25)
A disk that boots Linux through MILO is set up as follows:
- Give the disk a PC (MBR) partition table, not a BSD disklabel, since ARC and AlphaBIOS cannot read BSD disklabels. 26)
- Put the kernel on an ext2
/bootfile system; see Known issues for the file system limits.
Building
The alphalinux/milo repository contains releases 2.2-9 to 2.2-18 as imported commits, followed by work from 2026. That work vendors the Linux 2.2.26 sources, so that no external kernel tree is needed, and fixes building with a current cross-compiler. 29) make config selects the platform, and make then builds MILO with the cross-compiler named by CROSS_COMPILE, by default alpha-unknown-linux-gnu-. 30)
make config first asks for the path to the kernel sources, which is no longer used, then for the system type, and then for options such as serial console echo, its port and speed, and the file systems to include (ext2 by default; FAT, ReiserFS, and ISO 9660 are off). 31) 32) make oldconfig reuses an existing .config. A build for the Ruffian, for example: 33)
git clone https://github.com/alphalinux/milo.git cd milo make config # choose "Ruffian" as the Alpha system type make CROSS_COMPILE=alpha-linux-gnu- # or CROSS_COMPILE= on an Alpha
Every platform produces milo, the image loaded by linload.exe or ldmilo.exe. Most also produce milo.dd for an SRM boot floppy, and some also produce milo.rom or the flash utility fmu.gz, or both; the Ruffian build produces only milo and mboot. 34)
The released MILO 2.2 was instead built against a separately configured generic Linux 2.2 kernel, at least 2.2.18, without modules or sysctl support. 35) By 2007, that source could not be built with a current toolchain. 36)
Loading MILO
MILO can be loaded from ARC, AlphaBIOS, the SRM console, an evaluation board Debug Monitor, a fail-safe boot block floppy, or flash. 37) The build produces milo for booting from ARC or AlphaBIOS, milo.dd for writing to a floppy and booting from SRM, and milo.rom for flashing. 38)
From ARC or AlphaBIOS
ARC and AlphaBIOS run linload.exe, which passes the memory size and boot selection from the firmware to MILO and switches to MILO's PALcode. 39) linload.exe was built with the Windows NT ARC firmware tree and Microsoft tools, and its source was never released. 40) 41)
OSLOADFILENAMEnames the MILO image, so several MILO versions can be kept on the same partition. 44)- The
linload.exeversion must match MILO, or MILO gets the memory size wrong. 45) Version 1.3 or later is needed with more than 128 MiB of memory 46) and with AlphaBIOS: earlier versions load MILO at a fixed address, which crashes AlphaBIOS, while 1.3 searches the memory map for a free location. 1.3 also accepts a directory forOSLOADFILENAME, for AlphaBIOS versions that only accept a directory. 47) The Alpha XLT 366 needs the latest version. 48)
From SRM
On systems that also have SRM, milo.dd can be written to a floppy with dd and booted with boot dva0. 52) Booting Linux directly with aboot is simpler. 53)
From flash
On the AlphaPC 64, Noname, EB66+, EB164, and AlphaPC 164, MILO could also be written to flash with its Flash Management Utility and started directly. 54) MILO relies on the previous console for some hardware initialization, and Digital stopped supporting flashing it in 1998. 55)
Booting Linux
A kernel is booted with boot device:file followed by the kernel arguments, e.g.: 56) 57)
MILO> boot sda2:vmlinux.gz root=/dev/sda3 MILO> boot sda2:vmlinux.gz root=/dev/sda3 console=ttyS0
- When booted from ARC or AlphaBIOS, the system clock uses the ARC epoch. See ARC known issues.
initrd
MILO 2.2-17 and later load an initial ramdisk given with initrd=path on the command line. 68) The path has no device, since MILO only has one device open at a time. 69)
MILO runs at 13 MiB (0xd00000) and places the initrd directly below itself; if the initrd would reach down into the kernel, MILO refuses to load it. 70) 71) A kernel built with CONFIG_ALPHA_LEGACY_START_ADDRESS starts at 3 MiB, leaving less than 10 MiB for the kernel and initrd together. A kernel without it starts at 16 MiB, above MILO, so MILO cannot load any initrd for it. 72) A kernel for a MILO system therefore needs either a small initrd and the legacy start address, or no initrd, with the drivers for the root file system built in.
Configuration
milo.conf
MILO 2.2 reads a configuration file similar to lilo.conf when given boot with only a device, e.g. boot sda2:. 73) 74) It looks for /etc/milo.conf, then /milo.cfg. 75)
With /boot on sda2 and the root file system on sda3, paths are relative to sda2:
timeout = 50 image = /vmlinux.gz label = linux root = /dev/sda3 append = "console=ttyS0"
timeoutis in tenths of a second. It boots the first image; 0 means no time limit. 76)commandruns a MILO command when the file is read, or, inside an image section, just before booting that image. It can be repeated. 77)- Each
imagestarts a section, withlabel(case sensitive),root,append, anddevice. The image can include a device, e.g.sda1:/vmlinux.gz. 78) - At the MILO prompt,
boot sda2:followed by a label boots that image. 79)
miloctl
miloctl edits the parameter block inside a MILO image file (not the copy in memory): 80)
cmd=command sets a startup command, run when MILO is about to show its prompt, with one second to abort it.OSLOADOPTIONSoverrides it. A typical startup command isboot sda2:, which readsmilo.conf.mem=size overrides the memory size in MiB.+Sand+Vset theSERIAL_OUTPUTandVERBOSEflags, which are off by default.
For example, miloctl -v /dev/fd0 +S +V enables output to the serial port during startup on a MILO floppy. 81) A startup command and milo.conf can be combined by using the startup command only to point to milo.conf. 82) Linux itself needs console=ttyS0 to use the serial port; see Using the SRM Console: Serial console for the cabling and terminal settings.
Commands
The MILO 2.2 commands are: 83)
| Command | Description |
|---|---|
ls [path] | List files in a directory |
cd path | Change the current directory |
boot [path [arguments]] | Boot a kernel |
read [dev:] block | Read a block from a device |
run path | Run a standalone program |
show | Display all known devices and file systems |
sleep seconds | Wait |
pci | Display the PCI configuration |
set [variable value], unset variable | Set, display, or delete variables |
setenv, unsetenv, resetenv | Set or delete variables stored in NVRAM, instead of set and unset on systems with NVRAM support |
bootopt num | Select the firmware to start at power-on (Cabriolet, EB66+, EB164, and PC164 only) |
help | Print the command summary |
- Commands can be abbreviated, e.g.
b sda2:vmlinux.gz root=/dev/sda3. 86) - Adding
| moreto a command pages its output. 87) - MILO takes commands from both the keyboard and COM1 (see Known issues). 88)
Environment variables
| Variable | Description |
|---|---|
MEMORY_SIZE | Memory size in MiB |
BOOT_DEV, BOOT_FILE, BOOT_STRING | Default boot device, kernel file, and kernel arguments |
AUTOBOOT, AUTOBOOT_TIMEOUT | Boot at power-on, after a timeout in seconds |
SCSIn_HOSTID | Host ID of the nth SCSI controller (default 7) |
PCI_LATENCY | PCI bus master latency (default 32, maximum 255) |
CPU_CLOCK | CPU speed in MHz, for systems that report it wrongly |
VERBOSE | Print more information |
set MEMORY_SIZEis the usual workaround when MILO detects the wrong memory size. 95)
Known issues
- File systems: MILO has its own file system code, not the kernel's. 96) It reads ext2, MS-DOS, ISO 9660, and ReiserFS, 97) and reads ext3 as ext2, ignoring the journal. 98) It cannot read XFS, 99) or files stored in ext4 extents. Its ext2 code expects 1 KiB blocks, since it reads the block group descriptors from directly after the superblock, and 128-byte inodes, since it ignores the inode size recorded in the superblock. 100) Current
mke2fsuses 256-byte inodes, and 4 KiB blocks on all but small file systems, so/bootshould be a small ext2 file system created withmke2fs -t ext2 -b 1024 -I 128. 101) Alternatively, the kernel can be kept on the FAT partition next to MILO. 102) - Serial port: MILO is built by default with serial console support on COM1 at 9600 baud. It then always accepts input from COM1, but only echoes its output there once the
SERIAL_OUTPUTflag is set (see miloctl) or a character has been received on the port. 103) 104) 105) A modem or other device on COM1 can therefore fill the screen withO>and block input. 106) 107) - VGA behind a PCI bridge: MILO cannot initialize a VGA card behind a PCI-to-PCI bridge, e.g. in the 32-bit slots of the AlphaPC 164UX. 108)
- SCSI controllers: a controller can only be used if its driver is built into MILO. 109) MILO cannot be booted from a BusLogic controller (see ARC: Known issues). Driver options cannot be passed to MILO's drivers. 110)
- Low power idle: MILO's PALcode generally lacks the
wtintcall, which Nikita Schmidt added only for the Avanti. 113)
Design
MILO consists of PALcode, memory and video setup, block device drivers taken unmodified from the Linux kernel it is built against, its own file system code, a user interface, and the code that builds the HWRPB for Linux. 114) MILO does not configure network devices. 115)
PALcode
MILO's PALcode is based on the sample PALcode in Digital Semiconductor's Evaluation Board System Developers Kit (EBSDK). 116) The loader that starts MILO from ARC switches from the Windows NT PALcode to MILO's. 117) Each board has its own PALcode. Systems not built by Digital Semiconductor, such as the Avanti and Mikasa, use modified evaluation board PALcode. 118)
The EBSDK PALcode is less complete than the SRM PALcode: Digital supplied it as-is, for informational purposes, and recommended SRM wherever it was available. 119) It lacks access to the performance counters and support for the prefetch code generated by Compaq's C compiler, 120) ECC error reporting, 121) and the PAL calls needed by NetBSD and OpenBSD. 122) MILO also does not provide the SRM console callbacks. 123)
On many systems, the MILO and SRM PALcode deliver interrupts differently, so kernels built for one would not boot from the other. 124) On the Noname, UDB, Avanti, and Platform 2000, the same kernel boots from both. 125) Generic kernels run from either. 126)
Video
MILO uses a VGA card if one is present, otherwise a TGA card. 127) VGA cards are initialized by running their x86 BIOS in an emulator. 128)
HWRPB and rebooting
MILO builds the HWRPB and memory cluster descriptions that tell Linux the system type and the available memory. 129) Because it must describe the system itself, there is a separate MILO for each platform. 130) MILO sets the system serial number to MILO- followed by the version, e.g. MILO-2.0.35-c7, which lets Linux tools detect that MILO was used, 131) and each CPU's serial number to Linux_is_Great!. 132) 133) The kernel itself checks the MILO prefix of the system serial number to tell whether it was booted from SRM. 134) The UP1000's APB loader also uses MILO-0000. 135)
MILO leaves a compressed copy of itself in memory. When Linux reboots, it returns to that copy, which boots the same kernel with the same command after a 30 second timeout. 136) It is not possible to return to ARC. 137)
Licensing
MILO's LICENSE file contains three licenses: Digital's PALcode license, which allows use only in products with an Alpha processor; a license for the BIOS emulation libraries, which forbids modifying them; and the GNU GPL. 138) Most MILO source files carry a separate Digital notice that permits use, copying, modification, and distribution. 139) The LICENSE file and the source headers are therefore inconsistent about which parts are under the GPL. 140) linload.exe is not free, since it uses parts of the Windows NT SDK. 141)
History
David A. Rusling of Digital's European Semiconductor Applications Engineering group in Reading, England, wrote MILO and its Flash Management Utility. 142) 143) MILO was first released publicly in BLADE 0.2 on 9 August 1995, as a console firmware replacement for systems without SRM support. 144) Jay Estabrook took over MILO in 1997, when Rusling moved to StrongARM work. 145) Nikita Schmidt at University College Dublin maintained a separate branch from 1998 to 2000, which added /etc/milo.conf, a startup command stored in the image, and the miloctl tool, and was used by Debian, Red Hat, and SuSE. 146) 147)
Stefan Reinauer of SuSE ported Schmidt's sources to Linux 2.2 as MILO 2.2 in November 1999. 148) 149) Release 2.2-17 added initrd support and fixes for Linux 2.4, 150) and the last release, 2.2-18 in July 2001, support for the UDB flash ROM and ReiserFS. 151) An attempt to port MILO to Linux 2.4 hung during PCI initialization on all machines. 152)
Once Windows NT for Alpha was discontinued, MILO was only needed on systems without SRM. 153) Reinauer stopped working on MILO in 2004, 154) and development resumed in the alphalinux repository in 2026. 155)
Conflicting information
The following sources conflict with each other or with the account given above. They are listed here for further investigation.
- Whether MILO should be booted from SRM
- "Re: Bad Debian/Alpha potato rescue floppy image?", David Huggins-Daines, debian-alpha, 27 Mar 2000: "booting MILO from SRM is just a bad idea"
- "Re: Bad Debian/Alpha potato rescue floppy image?", Nikita Schmidt, debian-alpha, 28 Mar 2000: "Booting MILO from SRM is not always a bad idea."
- Large ext2 partitions
- "Re: Milo/kernel problem", Nikita Schmidt, axp-list, 18 Sep 1998: "Current MILO can't handle ext2fs partitions larger than 2Gb."
- "Re: Milo/kernel problem", Michal Jaegermann, axp-list, 19 Sep 1998: "This time milo had to read this 3.7G partition to load my kernel"
- Boards where MILO 2.2 works
- README.milo, MILO 2.2: "This version is known to work on LX164, SX164, Ruffian, Miata, but no successful tests on XL/XLT until now?"
- The same file, later: "These sources are currently working/tested on Ruffian, LX164, Avanti. It is untested on most other platforms."
- Size of the FAT partition for MILO
- "Re: UDB: Problems with fdisk", Jay Estabrook, axp-list, 15 Aug 1996: "partition 1: ~2Mb DOS format, to hold linload/MILO"
- "Re: milo", David Rusling, axp-list, 4 Nov 1996: "a small (~10Mbyte) DOS partition"
Documentation
| Document | Part number | Date |
|---|---|---|
| Alpha Miniloader Howto, v0.85 | April 1997 | |
| README.milo (MILO 2.2) | ||
| milo.conf(5) and miloctl(8) | ||
| ChangeLog (MILO 2.2) | ||
| milo-list archive (1999 to 2001) |
README, Linux-Alpha archive, ftp.digital.com, 19 Dec 1996
READ.ME, Miniloader directory, Linux-Alpha archive, ftp.digital.com, 26 Nov 1996
