Let's start at the very beginning: IPL aka Initial Program Load.
This is comparable to a boot of a PC or a device. Note that it is not the starting of the whole mainframe, but rather starting up a partition or virtual machine.2 You basically need to get your system into a state where your operating system takes control.
Classic IPL does the following:
- Do a lot of resets: All cpus will do a so-called "initial reset", and the I/O subsystem3 will also be reset.
- If it is a so-called "load-clear" operation, registers and storage (memory) will be cleared.
- A bootloader will be read from the I/O device that has been supplied to the load initiator4. Some parameters will also be passed.
- There's "CCW IPL", which is the oldest option and, in its canonical implementation, uses a very basic channel I/O operation to read data. We interpreted this a bit creatively for QEMU so that we can read from a virtio device instead.
- A newer option is "List-Directed IPL", which is used on real hardware to start from FCP-attached SCSI disks. We don't currently implement this in QEMU.
- We're also a bit inventive with other options for QEMU usage.
First of all, we need to save our options somewhere. This is handled in hw/s390x/ipl.c. Then, we need to perform the various resets - this can easily be done via the normal QEMU infrastructure. That's it for the host emulation.
To actually be able to start something, we need a component that runs in the guest and actually loads the operating system (and implements our own interpretation of the loading part of the IPL process). That's where we introduce something that does not normally exist on the s390: a "bios". In our case, the bios can be found in pc-bios/s390-ccw/ and handles reading from disks, interpreting the boot records found there and actually loading the subsequently started image. But that's out of the scope of a simple explanation of IPL and deserves its own post.
1. Originally, I wanted to call this "TLAs explained", but there are a lot of interesting FLAs as well.↩
2. Modern mainframes are always virtualized, i.e. you always run at least with a partinioning hypervisor (LPAR). Most people will also use a hypervisor like KVM/QEMU or z/VM in their partition.↩ 3. Articles about channel I/O will come in the future.↩ 4. On old machines, you did this with knobs on the panel. Today, there are masks you fill in or a command you give. Even the OS itself can initiate it via hypercall.↩