|
| 1 | +# Booting the BIOS |
| 2 | + |
| 3 | +After building our BIOS, we want to make sure we can boot it normally before we |
| 4 | +add our fuzzing harness. This time, we'll add our harness to the boot flow, before any |
| 5 | +UEFI shell, so it is prudent to make sure everything looks OK first. |
| 6 | + |
| 7 | +Before this step, you'll need to have the TSFFS SIMICS package installed in your system |
| 8 | +by following the [setup steps](../setup/README.md) or by installing a prebuilt `ispm` |
| 9 | +package. You'll also need the SIMICS base package (1000), the QSP-x86 package (2096), |
| 10 | +and the QSP-CPU (8112) package. All three are available in the public simics release. |
| 11 | + |
| 12 | +You can check that you have the package installed by running: |
| 13 | + |
| 14 | +```sh |
| 15 | +ispm packages --list-installed |
| 16 | +``` |
| 17 | + |
| 18 | +You should see (at least, but likely more packages): |
| 19 | + |
| 20 | +```txt |
| 21 | +Installed Base Packages |
| 22 | + Package Number Name Version Installed Paths |
| 23 | + 1000 Simics-Base 6.0.169 /home/rhart/simics/simics-6.0.169 |
| 24 | +
|
| 25 | +Installed Addon Packages |
| 26 | + Package Number Name Version Installed Paths |
| 27 | + 2096 QSP-x86 6.0.70 /home/rhart/simics/simics-qsp-x86-6.0.70 |
| 28 | + 8112 QSP-CPU 6.0.17 /home/rhart/simics/simics-qsp-cpu-6.0.17 |
| 29 | + 31337 TSFFS 6.0.1 /home/rhart/simics/simics-tsffs-6.0.1 |
| 30 | +``` |
| 31 | + |
| 32 | +in the list! |
| 33 | + |
| 34 | +## Create the Project |
| 35 | + |
| 36 | +We already created the `project` directory when we built our image, but we need to go |
| 37 | +ahead and initialize it and add the packages we need with `ispm`. |
| 38 | + |
| 39 | +```sh |
| 40 | +ispm projects project --create 1000-latest 2096-latest 8112-latest 31337-latest \ |
| 41 | + --ignore-existing-files |
| 42 | +``` |
| 43 | + |
| 44 | +We won't be using any custom UEFI applications, so we can skip the boot disk we used in |
| 45 | +other tutorials. We will, however, need to customize our boot script slightly. |
| 46 | + |
| 47 | +In the previous tutorials, we used the QSP-x86 package provided `qsp-x86/uefi-shell` |
| 48 | +target to boot directly to the UEFI shell without any extra steps. That target uses |
| 49 | +a script to choose the boot device for us, but because the included BIOS is both |
| 50 | +different from the one we're using and boots in release mode without debug output, we |
| 51 | +need to modify it somewhat to work with our custom BIOS. |
| 52 | + |
| 53 | +## Add SIMICS Targets |
| 54 | + |
| 55 | +A SIMICS "target" is a YAML file which declares configuration options that are |
| 56 | +ultimately passed to a script. It provides an easy way to configure and override options |
| 57 | +without digging through scripts to find the right configuration options. You can read |
| 58 | +more about targets |
| 59 | +[here](https://intel.github.io/tsffs/simics/simics-user-guide/targets.html). |
| 60 | + |
| 61 | +We'll create a new target in `project/targets/qsp-x86/qsp-uefi-custom.target.yml`: |
| 62 | + |
| 63 | +```yaml |
| 64 | +%YAML 1.2 |
| 65 | +--- |
| 66 | +description: QSP booting to EFI shell, defaults to empty disks |
| 67 | +params: |
| 68 | + machine: |
| 69 | + system_info: |
| 70 | + type: str |
| 71 | + description: A short string describing what this system is. |
| 72 | + default: "QSP x86 - UEFI Shell" |
| 73 | + hardware: |
| 74 | + import: "%simics%/targets/qsp-x86/hardware.yml" |
| 75 | + defaults: |
| 76 | + name: qsp |
| 77 | + rtc: |
| 78 | + time: auto |
| 79 | + usb_tablet: |
| 80 | + create: true |
| 81 | + firmware: |
| 82 | + bios: ^machine:software:firmware:bios |
| 83 | + lan_bios: |
| 84 | + spi_flash: ^machine:software:firmware:spi_flash |
| 85 | + uefi_device: |
| 86 | + advanced: 2 |
| 87 | + name: |
| 88 | + type: str |
| 89 | + default: simics_uefi |
| 90 | + description: | |
| 91 | + Name of a simics-uefi device added under the top component. |
| 92 | + video_mode: |
| 93 | + type: int |
| 94 | + default: 5 |
| 95 | + description: | |
| 96 | + Bochs GFX Mode to be set by UEFI BIOS during boot before OS handover. |
| 97 | + software: |
| 98 | + firmware: |
| 99 | + description: Firmware images |
| 100 | + advanced: 2 |
| 101 | + bios: |
| 102 | + type: file |
| 103 | + description: BIOS file. |
| 104 | + default: "%simics%/workspace/Build/SimicsOpenBoardPkg/BoardX58Ich10/DEBUG_GCC/FV/BOARDX58ICH10.fd" |
| 105 | + lan_bios: |
| 106 | + type: file |
| 107 | + required: false |
| 108 | + description: ROM BIOS file for the ICH10 LAN Ethernet adaptor |
| 109 | + spi_flash: |
| 110 | + type: file |
| 111 | + default: "%simics%/targets/qsp-x86/images/spi-flash.bin" |
| 112 | + description: The ICH10 SPI flash file to use. |
| 113 | + script_delay: |
| 114 | + type: int |
| 115 | + default: 1 |
| 116 | + description: Script delay multiplier during UEFI boot |
| 117 | + |
| 118 | + network: |
| 119 | + switch: |
| 120 | + import: "%simics%/targets/common/ethernet-setup.yml" |
| 121 | + service_node: |
| 122 | + import: "%simics%/targets/common/sn-setup.yml" |
| 123 | + defaults: |
| 124 | + ethernet_switch: ^network:switch:ethernet_switch:name |
| 125 | + |
| 126 | + output: |
| 127 | + system: |
| 128 | + type: str |
| 129 | + output: yes |
| 130 | + default: ^machine:hardware:output:system |
| 131 | +script: "%script%/qsp-uefi-custom.target.yml.include" |
| 132 | +... |
| 133 | +``` |
| 134 | + |
| 135 | +This target is copied more or less wholesale from the `uefi-shell.target.yml` file in |
| 136 | +your SIMICS QSP-x86 installation, but is modified to use a different default BIOS file, |
| 137 | +a different `.include` script, and uses a different path to import the top level |
| 138 | +`hardware.yml` script. |
| 139 | + |
| 140 | +We also need to provide a custom `.include` script, which is (as the name may suggest) |
| 141 | +included by the target and run on startup to configure the system. Most of this script |
| 142 | +is also copied from the `uefi-shell.target.yml.include` script with the exception of the |
| 143 | +final `script-branch`. This `script-branch` enters the BIOS boot menu and selects the |
| 144 | +UEFI shell from it after waiting for a print message that indicates the boot menu is |
| 145 | +visible. |
| 146 | + |
| 147 | +```simics |
| 148 | +run-script "%simics%/targets/qsp-x86/hardware.yml" namespace = machine:hardware |
| 149 | +
|
| 150 | +local $system = (params.get machine:hardware:output:system) |
| 151 | +
|
| 152 | +instantiate-components $system |
| 153 | +
|
| 154 | +# Add Simics UEFI meta-data device |
| 155 | +if (params.get machine:uefi_device:name) { |
| 156 | + @name = f"{simenv.system}.{params['machine:uefi_device:name']}" |
| 157 | + @dev = SIM_create_object("simics-uefi", name, []) |
| 158 | + @getattr(conf, simenv.system).mb.nb.pci_bus.devices.append([0, 7, dev]) |
| 159 | + @dev.video_mode = params['machine:uefi_device:video_mode'] |
| 160 | +} |
| 161 | +
|
| 162 | +## Name system |
| 163 | +$system->system_info = (params.get machine:system_info) |
| 164 | +
|
| 165 | +## Set a time quantum that provides reasonable performance |
| 166 | +set-time-quantum cell = $system.cell seconds = 0.0001 |
| 167 | +
|
| 168 | +## Set up Ethernet |
| 169 | +run-script "%simics%/targets/common/ethernet-setup.yml" namespace = network:switch |
| 170 | +if (params.get network:switch:create_network) { |
| 171 | + local $ethernet_switch = (params.get network:switch:ethernet_switch:name) |
| 172 | + connect ($ethernet_switch.get-free-connector) (params.get machine:hardware:output:eth_slot) |
| 173 | + instantiate-components (params.get network:switch:ethernet_switch:name) |
| 174 | +} |
| 175 | +run-script "%simics%/targets/common/sn-setup.yml" namespace = network:service_node |
| 176 | +
|
| 177 | +local $system = (params.get machine:hardware:output:system) |
| 178 | +
|
| 179 | +local $system = (params.get machine:hardware:output:system) |
| 180 | +
|
| 181 | +script-branch { |
| 182 | + local $con = $system.serconsole.con |
| 183 | + # NOTE: We have to modify this from the included target because |
| 184 | + # the custom BIOS doesn't print the original message until the menu appears |
| 185 | + bp.console_string.wait-for $con "End Load Options Dumping" |
| 186 | + bp.time.wait-for seconds = 5.0 |
| 187 | + echo "Got load options dump" |
| 188 | + echo "Opening EFI shell" |
| 189 | + $con.input -e Esc |
| 190 | + bp.time.wait-for seconds = 5.0 |
| 191 | +
|
| 192 | + $con.input -e Down |
| 193 | + $con.input -e Down |
| 194 | + $con.input -e Enter |
| 195 | + bp.time.wait-for seconds = 5.0 |
| 196 | +
|
| 197 | + foreach $i in (range 6) { |
| 198 | + $con.input -e Down |
| 199 | + } |
| 200 | +
|
| 201 | + $con.input -e Enter |
| 202 | + $con.input -e Enter |
| 203 | +} |
| 204 | +``` |
| 205 | + |
| 206 | +Save this file as `project/targets/qsp-x86/qsp-uefi-custom.target.yml.include`. |
| 207 | + |
| 208 | +## Test Booting The BIOS |
| 209 | + |
| 210 | +With our files all in place, we can create a tiny SIMICS script, and save it as |
| 211 | +`project/run.simics`: |
| 212 | + |
| 213 | +```simics |
| 214 | +load-target "qsp-x86/qsp-uefi-custom" namespace = qsp machine:hardware:firmware:bios = "%simics%/workspace/Build/SimicsOpenBoardPkg/BoardX58Ich10/DEBUG_GCC/FV/BOARDX58ICH10.fd" |
| 215 | +
|
| 216 | +script-branch { |
| 217 | + local $con = qsp.serconsole.con |
| 218 | + bp.console_string.wait-for $con "Shell>" |
| 219 | + bp.time.wait-for seconds = .5 |
| 220 | + qsp.serconsole.con.input "help\n" |
| 221 | + bp.time.wait-for seconds = .5 |
| 222 | +} |
| 223 | +
|
| 224 | +run |
| 225 | +``` |
| 226 | + |
| 227 | +Then run the script: |
| 228 | + |
| 229 | +```sh |
| 230 | +./simics -no-gui --no-win ./run.simics |
| 231 | +``` |
| 232 | + |
| 233 | +Somewhere in the output you should see: |
| 234 | + |
| 235 | +```txt |
| 236 | +<qsp.serconsole.con>Shell> help\r\n |
| 237 | +<qsp.serconsole.con>alias - Displays, creates, or deletes UEFI Shell aliases.\r\n |
| 238 | +<qsp.serconsole.con>attrib - Displays or modifies the attributes of files or directories.\r\n |
| 239 | +<qsp.serconsole.con>bcfg - Manages the boot and driver options that are stored in NVRAM.\r\n |
| 240 | +<qsp.serconsole.con>cd - Displays or changes the current directory.\r\n |
| 241 | +``` |
| 242 | + |
| 243 | +If you do, all is well! Notice that there is quite a bit more output due to being a |
| 244 | +debug build of the BIOS. |
0 commit comments