|
| 1 | +--- |
| 2 | +title: Set Up Pre-Silicon Development Environment for OpenBMC and UEFI |
| 3 | +weight: 3 |
| 4 | + |
| 5 | +### FIXED, DO NOT MODIFY |
| 6 | +layout: learningpathall |
| 7 | +--- |
| 8 | + |
| 9 | +## Set Up Development Environment |
| 10 | + |
| 11 | +In this module, you’ll prepare your workspace to build and simulate OpenBMC and UEFI firmware on the Neoverse RD-V3 platform using Arm Fixed Virtual Platforms (FVPs). |
| 12 | +You’ll install the required tools, configure repositories, and set up a Docker-based build environment for both BMC and host firmware. |
| 13 | + |
| 14 | +Before getting started, it’s strongly recommended to review the previous Learning Path: [CSS-V3 Pre-Silicon Software Development Using Neoverse Servers](https://learn.arm.com/learning-paths/servers-and-cloud-computing/neoverse-rdv3-swstack). |
| 15 | +That guide walks you through how to use the CSSv3 reference design on FVP to perform early-stage development and validation. |
| 16 | + |
| 17 | +Ensure your system meets the following requirements: |
| 18 | +- Access to an Arm Neoverse-based Linux machine (either cloud-based or local) is required, with at least 80 GB of free disk space, 48 GB of RAM, and running Ubuntu 22.04 LTS. |
| 19 | +- Working knowledge of Docker, Git, and Linux terminal tools |
| 20 | +- Basic understanding of server firmware stack (UEFI, BMC, TF-A, etc.) |
| 21 | +- Docker installed, or GitHub Codespaces-compatible development environment |
| 22 | + |
| 23 | +### Install Required Packages |
| 24 | + |
| 25 | +Install the base packages for building OpenBMC with the Yocto Project: |
| 26 | + |
| 27 | +```bash |
| 28 | +sudo apt update |
| 29 | +sudo apt install git gcc g++ make file wget gawk diffstat bzip2 cpio chrpath zstd lz4 bzip2 unzip |
| 30 | +``` |
| 31 | + |
| 32 | +### Set Up the repo Tool |
| 33 | + |
| 34 | +```bash |
| 35 | +mkdir -p ~/.bin |
| 36 | +PATH="${HOME}/.bin:${PATH}" |
| 37 | +curl https://storage.googleapis.com/git-repo-downloads/repo > ~/.bin/repo |
| 38 | +chmod a+rx ~/.bin/repo |
| 39 | +``` |
| 40 | + |
| 41 | +### Download the Arm FVP Model (RD-V3) |
| 42 | + |
| 43 | +Download and extract the RD-V3 FVP binary from Arm: |
| 44 | +```bash |
| 45 | +mkdir ~/fvp |
| 46 | +cd ~/fvp |
| 47 | +wget https://developer.arm.com/-/cdn-downloads/permalink/FVPs-Neoverse-Infrastructure/RD-V3-r1/FVP_RD_V3_R1_11.29_35_Linux64_armv8l.tgz |
| 48 | +tar -xvf FVP_RD_V3_R1_11.29_35_Linux64_armv8l.tgz |
| 49 | +./FVP_RD_V3_R1.sh |
| 50 | +``` |
| 51 | + |
| 52 | +The FVP installation may prompt you with a few questions—choosing the default options is sufficient for this learning path. By default, the FVP will be installed in /home/ubuntu/FVP_RD_V3_R1. |
| 53 | + |
| 54 | + |
| 55 | +### Initialize the Host Build Environment |
| 56 | + |
| 57 | +Set up a workspace for host firmware builds: |
| 58 | + |
| 59 | +```bash |
| 60 | +mkdir ~/host |
| 61 | +cd host |
| 62 | + |
| 63 | +~/.bin/repo init -u "https://git.gitlab.arm.com/infra-solutions/reference-design/infra-refdesign-manifests.git" \ |
| 64 | + -m "pinned-rdv3r1-bmc.xml" \ |
| 65 | + -b "refs/tags/RD-INFRA-2025.07.03" \ |
| 66 | + --depth=1 |
| 67 | + |
| 68 | +repo sync -c -j $(nproc) --fetch-submodules --force-sync --no-clone-bundle |
| 69 | +``` |
| 70 | + |
| 71 | +### Apply Required Patches |
| 72 | + |
| 73 | +To enable platform-specific functionality such as Redfish support and UEFI enhancements, apply a set of pre-defined patches from Arm’s GitLab repository. |
| 74 | + |
| 75 | +Use sparse checkout to download only the `patch/` folder: |
| 76 | + |
| 77 | +```bash |
| 78 | +cd ~/host |
| 79 | +git init |
| 80 | +git remote add -f origin https://gitlab.arm.com/server_management/PoCs/fvp-poc |
| 81 | +git config core.sparsecheckout true |
| 82 | +echo /patch >> .git/info/sparse-checkout |
| 83 | +git pull origin main |
| 84 | +``` |
| 85 | + |
| 86 | +This approach allows you to fetch only the `patch` folder from the remote Git repository—saving time and disk space. |
| 87 | + |
| 88 | +Next, create an `apply_patch.sh` script inside the `~` directory and paste in the following content. |
| 89 | +This script will automatically apply the necessary patches to each firmware component. |
| 90 | + |
| 91 | +```patch |
| 92 | +FVP_DIR="host" |
| 93 | +SOURCE=${PWD} |
| 94 | + |
| 95 | +GREEN='\033[0;32m' |
| 96 | +NC='\033[0m' |
| 97 | + |
| 98 | +pushd ${FVP_DIR} > /dev/null |
| 99 | +echo -e "${GREEN}\n===== Apply patches to edk2 =====\n${NC}" |
| 100 | +pushd uefi/edk2 |
| 101 | +git am --keep-cr ${SOURCE}/patch/edk2/*.patch |
| 102 | +popd > /dev/null |
| 103 | + |
| 104 | +echo -e "${GREEN}\n===== Apply patches to edk2-platforms =====\n${NC}" |
| 105 | +pushd uefi/edk2/edk2-platforms > /dev/null |
| 106 | +git am --keep-cr ${SOURCE}/patch/edk2-platforms/*.patch |
| 107 | +popd > /dev/null |
| 108 | + |
| 109 | +echo -e "${GREEN}\n===== Apply patches to edk2-redfish-client =====\n${NC}" |
| 110 | +git clone https://github.com/tianocore/edk2-redfish-client.git |
| 111 | +pushd edk2-redfish-client > /dev/null |
| 112 | +git checkout 4f204b579b1d6b5e57a411f0d4053b0a516839c8 |
| 113 | +git am --keep-cr ${SOURCE}/patch/edk2-redfish-client/*.patch |
| 114 | +popd > /dev/null |
| 115 | + |
| 116 | +echo -e "${GREEN}\n===== Apply patches to buildroot =====\n${NC}" |
| 117 | +pushd buildroot > /dev/null |
| 118 | +git am ${SOURCE}/patch/buildroot/*.patch |
| 119 | +popd > /dev/null |
| 120 | + |
| 121 | +echo -e "${GREEN}\n===== Apply patches to build-scripts =====\n${NC}" |
| 122 | +pushd build-scripts > /dev/null |
| 123 | +git am ${SOURCE}/patch/build-scripts/*.patch |
| 124 | +popd > /dev/null |
| 125 | +popd > /dev/null |
| 126 | +``` |
| 127 | + |
| 128 | +Run the patch script: |
| 129 | + |
| 130 | +```bash |
| 131 | +cd ~ |
| 132 | +chmod +x ./apply_patch.sh |
| 133 | +./apply_patch.sh |
| 134 | +``` |
| 135 | + |
| 136 | +This script automatically applies patches to edk2, edk2-platforms, buildroot, and related components. |
| 137 | +These patches enable additional UEFI features, integrate the Redfish client, and align the build system with the RD-V3 simulation setup. |
| 138 | + |
| 139 | +### Build RDv3 R1 Host Docker Image |
| 140 | + |
| 141 | +Before building the host image, update the following line in `~/host/grub/bootstrap` to replace the `git://` protocol. |
| 142 | +Some networks or corporate environments restrict `git://` access due to firewall or security policies. Switching to `https://` ensures reliable and secure access to external Git repositories. |
| 143 | + |
| 144 | +``` |
| 145 | +diff --git a/bootstrap b/bootstrap |
| 146 | +index 5b08e7e2d..031784582 100755 |
| 147 | +--- a/bootstrap |
| 148 | ++++ b/bootstrap |
| 149 | +@@ -47,7 +47,7 @@ PERL="${PERL-perl}" |
| 150 | + me=$0 |
| 151 | +-default_gnulib_url=git://git.sv.gnu.org/gnulib |
| 152 | ++default_gnulib_url=https://git.savannah.gnu.org/git/gnulib.git |
| 153 | +usage() { |
| 154 | + cat <<EOF |
| 155 | +``` |
| 156 | + |
| 157 | +This command builds the Docker image used for compiling the host firmware components in a controlled environment. |
| 158 | + |
| 159 | +```bash |
| 160 | +cd ~/host/container-scripts |
| 161 | +./container.sh build |
| 162 | +``` |
| 163 | + |
| 164 | +Within the `host` directory, run: |
| 165 | + |
| 166 | +```bash |
| 167 | +docker run --rm \ |
| 168 | + -v $HOME/host:$HOME/host \ |
| 169 | + -w $HOME/host \ |
| 170 | + --env ARCADE_USER=$(id -un) \ |
| 171 | + --env ARCADE_UID=$(id -u) \ |
| 172 | + --env ARCADE_GID=$(id -g) \ |
| 173 | + -t -i rdinfra-builder \ |
| 174 | + bash -c "./build-scripts/rdinfra/build-test-busybox.sh -p rdv3r1 all" |
| 175 | +``` |
| 176 | + |
| 177 | +Once complete, you can observe the build binary in `~/host/output/rdv3r1/rdv3r1/` |
| 178 | + |
| 179 | +``` |
| 180 | +ls -la host/output/rdv3r1/rdv3r1/ |
| 181 | +total 4308 |
| 182 | +drwxr-xr-x 2 ubuntu ubuntu 4096 Aug 18 10:19 . |
| 183 | +drwxr-xr-x 4 ubuntu ubuntu 4096 Aug 18 10:20 .. |
| 184 | +lrwxrwxrwx 1 ubuntu ubuntu 25 Aug 18 10:19 Image -> ../components/linux/Image |
| 185 | +lrwxrwxrwx 1 ubuntu ubuntu 35 Aug 18 10:19 Image.defconfig -> ../components/linux/Image.defconfig |
| 186 | +-rw-r--r-- 1 ubuntu ubuntu 4402315 Aug 18 10:19 fip-uefi.bin |
| 187 | +lrwxrwxrwx 1 ubuntu ubuntu 34 Aug 18 10:19 lcp_ramfw.bin -> ../components/rdv3r1/lcp_ramfw.bin |
| 188 | +lrwxrwxrwx 1 ubuntu ubuntu 33 Aug 18 10:19 lcp_ramfw_ns -> ../components/rdv3r1/lcp_ramfw_ns |
| 189 | +lrwxrwxrwx 1 ubuntu ubuntu 26 Aug 18 10:19 lkvm -> ../components/kvmtool/lkvm |
| 190 | +lrwxrwxrwx 1 ubuntu ubuntu 34 Aug 18 10:19 mcp_ramfw.bin -> ../components/rdv3r1/mcp_ramfw.bin |
| 191 | +lrwxrwxrwx 1 ubuntu ubuntu 33 Aug 18 10:19 mcp_ramfw_ns -> ../components/rdv3r1/mcp_ramfw_ns |
| 192 | +lrwxrwxrwx 1 ubuntu ubuntu 28 Aug 18 10:19 rmm.img -> ../components/rdv3r1/rmm.img |
| 193 | +lrwxrwxrwx 1 ubuntu ubuntu 34 Aug 18 10:19 scp_ramfw.bin -> ../components/rdv3r1/scp_ramfw.bin |
| 194 | +lrwxrwxrwx 1 ubuntu ubuntu 33 Aug 18 10:19 scp_ramfw_ns -> ../components/rdv3r1/scp_ramfw_ns |
| 195 | +lrwxrwxrwx 1 ubuntu ubuntu 41 Aug 18 10:19 signed_lcp_ramfw.bin -> ../components/rdv3r1/signed_lcp_ramfw.bin |
| 196 | +lrwxrwxrwx 1 ubuntu ubuntu 41 Aug 18 10:19 signed_mcp_ramfw.bin -> ../components/rdv3r1/signed_mcp_ramfw.bin |
| 197 | +lrwxrwxrwx 1 ubuntu ubuntu 41 Aug 18 10:19 signed_scp_ramfw.bin -> ../components/rdv3r1/signed_scp_ramfw.bin |
| 198 | +lrwxrwxrwx 1 ubuntu ubuntu 31 Aug 18 10:19 tf-bl1.bin -> ../components/rdv3r1/tf-bl1.bin |
| 199 | +lrwxrwxrwx 1 ubuntu ubuntu 30 Aug 18 10:19 tf-bl1_ns -> ../components/rdv3r1/tf-bl1_ns |
| 200 | +lrwxrwxrwx 1 ubuntu ubuntu 31 Aug 18 10:19 tf-bl2.bin -> ../components/rdv3r1/tf-bl2.bin |
| 201 | +lrwxrwxrwx 1 ubuntu ubuntu 32 Aug 18 10:19 tf-bl31.bin -> ../components/rdv3r1/tf-bl31.bin |
| 202 | +lrwxrwxrwx 1 ubuntu ubuntu 55 Aug 18 10:19 tf_m_flash.bin -> ../components/arm/rse/neoverse_rd/rdv3r1/tf_m_flash.bin |
| 203 | +lrwxrwxrwx 1 ubuntu ubuntu 48 Aug 18 10:19 tf_m_rom.bin -> ../components/arm/rse/neoverse_rd/rdv3r1/rom.bin |
| 204 | +lrwxrwxrwx 1 ubuntu ubuntu 50 Aug 18 10:19 tf_m_vm0_0.bin -> ../components/arm/rse/neoverse_rd/rdv3r1/vm0_0.bin |
| 205 | +lrwxrwxrwx 1 ubuntu ubuntu 50 Aug 18 10:19 tf_m_vm0_1.bin -> ../components/arm/rse/neoverse_rd/rdv3r1/vm0_1.bin |
| 206 | +lrwxrwxrwx 1 ubuntu ubuntu 50 Aug 18 10:19 tf_m_vm1_0.bin -> ../components/arm/rse/neoverse_rd/rdv3r1/vm1_0.bin |
| 207 | +lrwxrwxrwx 1 ubuntu ubuntu 50 Aug 18 10:19 tf_m_vm1_1.bin -> ../components/arm/rse/neoverse_rd/rdv3r1/vm1_1.bin |
| 208 | +lrwxrwxrwx 1 ubuntu ubuntu 33 Aug 18 10:19 uefi.bin -> ../components/css-common/uefi.bin |
| 209 | +``` |
| 210 | + |
| 211 | + |
| 212 | +{{% notice Note %}} |
| 213 | +The other [Arm Learning Path](https://learn.arm.com/learning-paths/servers-and-cloud-computing/neoverse-rdv3-swstack/3_rdv3_sw_build/) provides a complete introduction to setting up the RDv3 development environment — feel free to refer to it for more details. |
| 214 | +{{% /notice %}} |
| 215 | + |
| 216 | + |
| 217 | +### Build OpenBMC Image |
| 218 | + |
| 219 | +OpenBMC is built on the Yocto Project, which uses BitBake as its build tool. |
| 220 | +You don’t need to download BitBake separately, as it is included in the OpenBMC build environment. |
| 221 | +Once you’ve set up the OpenBMC repository and initialized the build environment, BitBake is already available for building images, compiling packages, or running other tasks. |
| 222 | + |
| 223 | +Start by cloning and building the OpenBMC image using the bitbake build system: |
| 224 | + |
| 225 | +```bash |
| 226 | +cd ~ |
| 227 | +git clone https://github.com/openbmc/openbmc.git |
| 228 | +cd ~/openbmc |
| 229 | +source setup fvp |
| 230 | +bitbake obmc-phosphor-image |
| 231 | +``` |
| 232 | + |
| 233 | +During the OpenBMC build process, you may encounter a native compilation error when building Node.js (especially version 22+) due to high memory usage during the V8 engine build phase depends on your build machine. |
| 234 | + |
| 235 | +```log |
| 236 | +g++: fatal error: Killed signal terminated program cc1plus |
| 237 | +compilation terminated. |
| 238 | +ERROR: oe_runmake failed |
| 239 | +``` |
| 240 | + |
| 241 | +This is a typical Out-of-Memory (OOM) failure, where the system forcibly terminates the compiler due to insufficient available memory. |
| 242 | + |
| 243 | +To reduce memory pressure, explicitly limit parallel tasks in `conf/local.conf`: |
| 244 | + |
| 245 | +```bash |
| 246 | +BB_NUMBER_THREADS = "2" |
| 247 | +PARALLEL_MAKE = "-j2" |
| 248 | +``` |
| 249 | + |
| 250 | +This ensures that BitBake only runs two parallel tasks and that each Makefile invocation limits itself to two threads. It significantly reduces peak memory usage and avoids OOM terminations. |
| 251 | + |
| 252 | +Once success build, you should see a successful build message similar to: |
| 253 | + |
| 254 | +``` |
| 255 | +Loading cache: 100% | | ETA: --:--:-- |
| 256 | +Loaded 0 entries from dependency cache. |
| 257 | +Parsing recipes: 100% |#############################################################################################################| Time: 0:00:09 |
| 258 | +Parsing of 3054 .bb files complete (0 cached, 3054 parsed). 5148 targets, 770 skipped, 0 masked, 0 errors. |
| 259 | +NOTE: Resolving any missing task queue dependencies |
| 260 | +
|
| 261 | +Build Configuration: |
| 262 | +BB_VERSION = "2.12.0" |
| 263 | +BUILD_SYS = "aarch64-linux" |
| 264 | +NATIVELSBSTRING = "ubuntu-22.04" |
| 265 | +TARGET_SYS = "aarch64-openbmc-linux" |
| 266 | +MACHINE = "fvp" |
| 267 | +DISTRO = "openbmc-phosphor" |
| 268 | +DISTRO_VERSION = "nodistro.0" |
| 269 | +TUNE_FEATURES = "aarch64 armv8-4a" |
| 270 | +TARGET_FPU = "" |
| 271 | +meta |
| 272 | +meta-oe |
| 273 | +meta-networking |
| 274 | +meta-python |
| 275 | +meta-phosphor |
| 276 | +meta-arm |
| 277 | +meta-arm-toolchain |
| 278 | +meta-arm-bsp |
| 279 | +meta-evb |
| 280 | +meta-evb-fvp-base = "master:1b6b75a7d22262ec1bf5ab8e2bfa434ac84d981b" |
| 281 | +
|
| 282 | +Sstate summary: Wanted 0 Local 0 Mirrors 0 Missed 0 Current 2890 (0% match, 100% complete)############################### | ETA: 0:00:00 |
| 283 | +Initialising tasks: 100% |##########################################################################################################| Time: 0:00:03 |
| 284 | +NOTE: Executing Tasks |
| 285 | +``` |
| 286 | + |
| 287 | +This confirms that the OpenBMC image was built successfully. |
| 288 | + |
| 289 | +{{% notice Note %}} |
| 290 | +The first build may take up to an hour depending on your system performance, as it downloads and compiles the entire firmware stack. |
| 291 | +{{% /notice %}} |
| 292 | + |
| 293 | +Your workspace should now follow a structured layout that separates the FVP simulator, host build system, OpenBMC source, and patches—making it easier to organize, maintain, and troubleshoot your simulation environment. |
| 294 | + |
| 295 | +```text |
| 296 | +├── FVP_RD_V3_R1 |
| 297 | +├── apply_patch.sh |
| 298 | +├── fvp |
| 299 | +│ ├── FVP_RD_V3_R1.sh |
| 300 | +│ ├── FVP_RD_V3_R1_11.29_35_Linux64_armv8l.tgz |
| 301 | +│ └── license_terms |
| 302 | +├── host |
| 303 | +│ ├── build-scripts |
| 304 | +│ ├── buildroot |
| 305 | +│ ├── patch |
| 306 | +│ │ ├── build-scripts |
| 307 | +│ │ ├── buildroot |
| 308 | +│ │ ├── edk2 |
| 309 | +│ │ ├── edk2-platforms |
| 310 | +│ │ └── edk2-redfish-client |
| 311 | +│ ├── ... |
| 312 | +├── openbmc |
| 313 | +│ ├── ... |
| 314 | +│ ├── build |
| 315 | +│ ├── meta-arm |
| 316 | +│ ├── ... |
| 317 | +│ ├── poky |
| 318 | +│ └── setup |
| 319 | +└── run.sh |
| 320 | +`` |
| 321 | +
|
| 322 | +With both the OpenBMC and host firmware environments built and configured, you’re now fully prepared to launch the full system simulation and observe the boot process in action. |
0 commit comments