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