1# OpenBMC Hello World using devtool 2 3**Document Purpose:** Walk through compiling and running an OpenBMC application 4in QEMU. 5 6**Prerequisites:** Completed Development Environment Setup 7[Document](https://github.com/openbmc/docs/blob/master/development/dev-environment.md) 8 9## Clone and Build a Repo 10 11devtool is a command line tool provided by the yocto distribution that allows 12you to extract a targeted repositories source code into your local bitbake 13environment and modify it. 14 15Today we'll be extracting the 16[phosphor-state-manager](https://github.com/openbmc/phosphor-state-manager.git) 17repository using devtool and modifying it. 18 19This assumes you have followed the first tutorial and are in the bitbake 20environment, right after doing the ". setup" command. 21 221. Use devtool to extract source code 23 24 ``` 25 devtool modify phosphor-state-manager 26 ``` 27 28 The above command will output the directory the source code is contained in. 29 302. Modify a source file and add a cout 31 32 ``` 33 vi workspace/sources/phosphor-state-manager/bmc_state_manager_main.cpp 34 ``` 35 36 Your diff should look something like this: 37 38 ``` 39 +#include <iostream> 40 41 int main(int argc, char**) 42 { 43 @@ -17,6 +18,8 @@ int main(int argc, char**) 44 45 bus.request_name(BMC_BUSNAME); 46 47 + std::cout<<"Hello World" <<std::endl; 48 + 49 while (true) 50 { 51 ``` 52 533. Rebuild the flash image which will now include your change 54 55 This will be a much faster build as bitbake will utilize all of the cache 56 from your previous build, only building what is new. 57 58 ``` 59 bitbake obmc-phosphor-image 60 ``` 61 62 Follow the steps in the first tutorial to load your new image into a QEMU 63 session and boot it up. 64 654. Confirm your "Hello World" made it into the new image 66 67 After you login to your QEMU session, verify the message is in the journal 68 69 ``` 70 journalctl | grep "Hello World" 71 ``` 72 73 You should see something like this: 74 75 ``` 76 <date> romulus phosphor-bmc-state-manager[1089]: Hello World 77 ``` 78 79You made a change, rebuilt the flash image to contain that change, and then 80booted that image up and verified the change made it in! 81 82## Loading an Application Directly Into a Running QEMU 83 84In this section we're going to modify the same source file, but instead of fully 85re-generating the flash image and booting QEMU again, we're going to just build 86the required binary and copy it into the running QEMU session and launch it. 87 881. Modify your hello world 89 90 ``` 91 vi workspace/sources/phosphor-state-manager/bmc_state_manager_main.cpp 92 ``` 93 94 Change your cout to "Hello World Again" 95 962. Bitbake only the phosphor-state-manager repository 97 98 Within bitbake, you can build only the repository (and it's dependencies) 99 that you are interested in. In this case, we'll just rebuild the 100 phosphor-state-manager repo to pick up your new hello world change. 101 102 ``` 103 bitbake phosphor-state-manager 104 ``` 105 106 Your new binary will be located at the following location relative to your 107 bitbake directory: 108 `./workspace/sources/phosphor-state-manager/oe-workdir/package/usr/bin/phosphor-bmc-state-manager` 109 1103. Create a safe file system for your application 111 112 Now is time to load your Hello World application in to QEMU virtual hardware. 113 The OpenBMC overrides the PATH variable to always look in /usr/local/bin/ 114 first so you could simply scp your application in to /usr/local/bin, run it 115 and be done. That works fine for command line tests, but when you start 116 launching your applications via systemd services you will hit problems since 117 application paths are hardcoded in the service files. Let's start our journey 118 doing what the professionals do and create an overlay file system. Overlays 119 will save you time and grief. No more renaming and recovering original files, 120 no more forgetting which files you messed with during debug, and of course, 121 no more bricking the system. Log in to the QEMU instance and run these 122 commands. 123 124 ``` 125 mkdir -p /tmp/persist/usr 126 mkdir -p /tmp/persist/work/usr 127 mount -t overlay -o lowerdir=/usr,upperdir=/tmp/persist/usr,workdir=/tmp/persist/work/usr overlay /usr 128 ``` 129 1304. scp this binary onto your QEMU instance 131 132 If you used the default ports when starting QEMU then here is the scp command 133 to run from your phosphor-state-manager directory. If you chose your own port 134 then substitute that here for the 2222. 135 136 ``` 137 scp -P 2222 ./workspace/sources/phosphor-state-manager/oe-workdir/package/usr/bin/phosphor-bmc-state-manager root@127.0.0.1:/usr/bin/ 138 ``` 139 140## Run the Application in QEMU 141 1421. Stop the BMC state manager service 143 144 ``` 145 systemctl stop xyz.openbmc_project.State.BMC.service 146 ``` 147 1482. Run the application in your QEMU session: 149 150 ``` 151 phosphor-bmc-state-manager 152 ``` 153 154 You'll see your "Hello World Again" message displayed. Ctrl^C to end that 155 application. In general, this is not how you will test new applications. 156 Instead, you'll be using systemd services. 157 1583. Start application via systemd service 159 160 OpenBMC uses systemd to manage its applications. There will be later 161 tutorials on this, but for now just run the following to restart the BMC 162 state service and have it pick up your new application: 163 164 ``` 165 systemctl restart xyz.openbmc_project.State.BMC.service 166 ``` 167 168 Since systemd started your service, the "Hello World Again" will not be 169 output to the console, but it will be in the journal. Later tutorials will 170 discuss the journal but for now just run: 171 172 ``` 173 journalctl | tail 174 ``` 175 176 You should see something like this in one of the journal entries: 177 178 ``` 179 <date> romulus phosphor-bmc-state-manager[1089]: Hello World Again 180 ``` 181 182That's it! You customized an existing BMC application, built it using devtool, 183and ran it within QEMU by both regenerating the entire flash image and patching 184it on via scp! 185 186## Advanced Workflow 187 188Once you've got a good handle on the above, there are some more advanced tools 189and wrappers you can utilize to optimize this flow. See this 190[link](https://amboar.github.io/notes/2022/01/13/openbmc-development-workflow.html) 191for more information. 192