Jekyll2023-01-17T23:12:00+00:00http://amandafalke.com/feed_igalia.xmlAmanda Falke's tech blog - Planet IgaliaPosts related to Planet Igalia on Amanda Falke's blogTutorial: Building WPE WebKit for Raspberry Pi 32023-01-17T08:03:00+00:002023-01-17T08:03:00+00:00http://amandafalke.com//igalia/2023/01/17/building-wpe-webkit-for-raspberry-pi-3-tutorial<blockquote>
<p>A lightning guide for building WPE WebKit with buildroot</p>
</blockquote>
<p>This tutorial will be for getting “up and running” with WPE WebKit using a Raspberry Pi 3 using a laptop/desktop with Linux Fedora installed. WPE WebKit has many benefits; you may <a href="https://wpewebkit.org/about/a-good-choice.html">read here about why WPE WebKit is a great choice for embedded devices</a>. WPE WebKit has minimal dependencies and it displays high-quality animations, WebGL and videos on embedded devices.</p>
<p><a href="https://github.com/WebPlatformForEmbedded">WebPlatformForEmbedded</a> is our focus; for this tutorial, we’ll be building WPE WebKit with buildroot to build our image, so, make sure to <a href="https://github.com/WebPlatformForEmbedded/buildroot">clone the buildroot repository</a>.</p>
<h2 id="you-will-need">You will need:</h2>
<blockquote>
<p>Raspberry pi 3 items:</p>
</blockquote>
<ul>
<li>A raspberry pi 3.</li>
<li>A microSD card for the pi. (I usually choose 32GB microSD cards).</li>
<li>An external monitor, extra mouse, and extra keyboard for our rpi3, separately from the laptop.</li>
<li>An HDMI cable to connect the rpi3 to its own external monitor.</li>
</ul>
<blockquote>
<p>Laptop items:</p>
</blockquote>
<ul>
<li>Linux laptop/desktop.
<ul>
<li>This tutorial will be based on Fedora, but you can use Debian or any distro of your choice.</li>
</ul>
</li>
<li>You also need a way to interface the microSD card with your laptop. You can get an SD Adapter for laptops that have an SD Card adapter slot, or you can use an external SD Card adapter interface for your computer.
<ul>
<li>This tutorial will be based on having a laptop with an SD card slot, and hence an SD Card Adapter will work just fine.</li>
</ul>
</li>
</ul>
<blockquote>
<p>Items for laptop to communicate with rpi3:</p>
</blockquote>
<ul>
<li>An ethernet cable to connect the rpi3 to your laptop.</li>
<li>You need some way to get ethernet into your laptop. This is either in the form of an ethernet port on your laptop (not likely), or an adapter of some sort (likely a USB adapter).</li>
</ul>
<h2 id="steps-high-level-overview">Steps: High level overview</h2>
<blockquote>
<p>This is a high level overview of the steps we will be taking.</p>
</blockquote>
<ol>
<li>Partition the blank SD card.</li>
<li>In the <code class="language-plaintext highlighter-rouge">buildroot</code> repository, <code class="language-plaintext highlighter-rouge">make <desired_config></code>.</li>
<li>Run the <code class="language-plaintext highlighter-rouge">buildroot</code> <code class="language-plaintext highlighter-rouge">menuconfig</code> with <code class="language-plaintext highlighter-rouge">make menuconfig</code> to set up <code class="language-plaintext highlighter-rouge">.config</code> file.</li>
<li>Run <code class="language-plaintext highlighter-rouge">make</code> to build <code class="language-plaintext highlighter-rouge">sdcard.img</code> in <code class="language-plaintext highlighter-rouge">buildroot/output</code> dir; change <code class="language-plaintext highlighter-rouge">.config</code> settings as needed.</li>
<li>Write <code class="language-plaintext highlighter-rouge">sdcard.img file</code> to the SD card.</li>
<li>Connect the rpi3 to its own external monitor, and its own mouse and keyboard.</li>
<li>Connect the rpi3 to the laptop using ethernet cable.</li>
<li>Put the SD card into the rpi3.</li>
<li>Setup a shared ethernet connection between the laptop and rpi to get the IP address of rpi.</li>
<li>ssh into the rpi and start WPE WebKit.</li>
</ol>
<h2 id="steps-detailed-overviewsequence">Steps: Detailed overview/sequence</h2>
<h3 id="1-partition-the-blank-sd-card-using-fdisk-create-a-boot-partition-and-a-root-partition">1. Partition the blank SD card using <code class="language-plaintext highlighter-rouge">fdisk</code>. Create a boot partition and a root partition.</h3>
<ul>
<li>Note: this is only needed in case the output image format is root.tar. If it’s sdcard.img, then that is dumped directly to the sdcard, that image is already partitioned internally.</li>
<li>If you’re unfamiliar with fdisk, <a href="https://www.nayab.xyz/linux-tools/partitioning-using-fdisk">this is a good tutorial</a>.</li>
</ul>
<h3 id="2-in-the-buildroot-repository-root-directory-make-the-desired-config">2. In the <code class="language-plaintext highlighter-rouge">buildroot</code> repository root directory, <code class="language-plaintext highlighter-rouge">make</code> the desired config.</h3>
<ul>
<li>Make sure to <a href="https://github.com/WebPlatformForEmbedded/buildroot">clone the buildroot repository</a>.</li>
<li>Since things change a lot over time, it’s important to note the specific <a href="https://github.com/WebPlatformForEmbedded/buildroot/commit/ce9dd9a89a90a50920ca34e2af4a185947123390">buildroot commit</a> this tutorial was built on, and that this tutorial was built on January 12th, 2023. It is recommended to build from that commit for consistency to ensure that the tutorial works for you.</li>
<li>We are building the <code class="language-plaintext highlighter-rouge">cog</code> <code class="language-plaintext highlighter-rouge">2.28</code> wpe with buildroot. See the build options from the <a href="https://github.com/WebPlatformForEmbedded/buildroot">buildroot repository</a>.</li>
<li>Run <code class="language-plaintext highlighter-rouge">make list-defconfigs</code> to get a list of configurations.</li>
<li>Copy <code class="language-plaintext highlighter-rouge">raspberrypi3_wpe_2_28_cog_defconfig</code> and run it: <code class="language-plaintext highlighter-rouge">make raspberrypi3_wpe_2_28_cog_defconfig</code>.</li>
<li>You will quickly get output which indicates that a <code class="language-plaintext highlighter-rouge">.config</code> file has been written in the root directory of the buildroot repository.</li>
</ul>
<h3 id="3-run-the-buildroot-menuconfig-with-make-menuconfig-to-set-up-config-file">3. Run the <code class="language-plaintext highlighter-rouge">buildroot</code> <code class="language-plaintext highlighter-rouge">menuconfig</code> with <code class="language-plaintext highlighter-rouge">make menuconfig</code> to set up <code class="language-plaintext highlighter-rouge">.config</code> file.</h3>
<ul>
<li>Run <code class="language-plaintext highlighter-rouge">make menuconfig</code>. You’ll see options here for configuration. Go slowly and be careful.</li>
<li>Change these settings. Help menus are available for <code class="language-plaintext highlighter-rouge">menuconfig</code>, you’ll see them displayed on the screen.</li>
</ul>
<table>
<thead>
<tr>
<th>Operation in menuconfig</th>
<th>Location</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr>
<td>ENABLE</td>
<td>Target packages -> Filesystem and flash utilities</td>
<td>dosfstools</td>
</tr>
<tr>
<td>ENABLE</td>
<td>Target packages -> Filesystem and flash utilities</td>
<td>mtools</td>
</tr>
<tr>
<td>ENABLE</td>
<td>Filesystem images</td>
<td>ext2/3/4 root filesystem</td>
</tr>
<tr>
<td>SET VALUE</td>
<td>Filesystem images -> ext2/3/4 root filesystem -> ext2/3/4 variant</td>
<td>ext4</td>
</tr>
<tr>
<td>DISABLE</td>
<td>Filesystem images</td>
<td>initial RAM filesystem linked into linux kernel</td>
</tr>
</tbody>
</table>
<h3 id="4-run-make-to-build-sdcardimg-in-buildrootoutput-dir-change-config-settings-as-needed">4. Run <code class="language-plaintext highlighter-rouge">make</code> to build <code class="language-plaintext highlighter-rouge">sdcard.img</code> in <code class="language-plaintext highlighter-rouge">buildroot/output</code> dir; change <code class="language-plaintext highlighter-rouge">.config</code> settings as needed.</h3>
<ul>
<li>
<p>Run <code class="language-plaintext highlighter-rouge">make</code>. Then get a coffee as the build and cross-compilation will take awhile.</p>
</li>
<li>In reality, you may encounter some errors along the way, as cross-compilation can be an intricate matter.
This tutorial will guide you through those potential errors.</li>
<li>When you encounter errors, you’ll follow a “loop” of sorts:
<blockquote>
<blockquote>
<p>Run <code class="language-plaintext highlighter-rouge">make</code> -> encounter errors -> manually edit <code class="language-plaintext highlighter-rouge">.config</code> file -> -> remove <code class="language-plaintext highlighter-rouge">buildroot/output</code> dir -> run <code class="language-plaintext highlighter-rouge">make</code> again until <code class="language-plaintext highlighter-rouge">sdcard.img</code> is built successfully.</p>
</blockquote>
</blockquote>
</li>
<li>If you encounter CMake errors, such as <code class="language-plaintext highlighter-rouge">fatal error: stdlib.h: No such file or directory, compilation terminated</code>, and you have a relatively new version of CMake on your system, the reason for the error may be that buildroot is using your local CMake instead of the one specified in the buildroot configuration.
<ul>
<li>We will fix this error by setting in <code class="language-plaintext highlighter-rouge">.config</code> file: <code class="language-plaintext highlighter-rouge">BR2_FORCE_HOST_BUILD=y</code>. Then remove <code class="language-plaintext highlighter-rouge">buildroot/output</code> dir, and run <code class="language-plaintext highlighter-rouge">make</code> again.</li>
</ul>
</li>
<li>If you encounter error such as <code class="language-plaintext highlighter-rouge">path/to/buildroot/output/host/lib/gcc/arm-buildroot-linux-gnueabihf/9.2.0/plugin/include/builtins.h:23:10: fatal error: mpc.h: No such file or directory</code>:</li>
<li>then we can fix this error by changing Makefile in <code class="language-plaintext highlighter-rouge">./output/build/linux-rpi-5.10.y/scripts/gcc-plugins/Makefile</code>, by adding <code class="language-plaintext highlighter-rouge">-I path/to/buildroot/output/host/include</code> in <code class="language-plaintext highlighter-rouge">plugin_cxxflags</code> stanza. Then, as usual, remove <code class="language-plaintext highlighter-rouge">buildroot/output</code> dir, and run <code class="language-plaintext highlighter-rouge">make</code> again.</li>
</ul>
<h3 id="5-write-sdcardimg-file-to-the-sd-card">5. Write <code class="language-plaintext highlighter-rouge">sdcard.img file</code> to the SD card.</h3>
<ul>
<li>At this point after the <code class="language-plaintext highlighter-rouge">make</code> process, we should have <code class="language-plaintext highlighter-rouge">sdcard.img</code> file in <code class="language-plaintext highlighter-rouge">buildroot/output/images</code> directory.</li>
<li>Write this file to the SD card.</li>
<li>Consider using Etcher to do so.</li>
</ul>
<h3 id="6-connect-the-rpi3-to-its-own-external-monitor-and-its-own-mouse-and-keyboard">6. Connect the rpi3 to its own external monitor, and its own mouse and keyboard.</h3>
<ul>
<li>We’ll have separate monitor, mouse and keyboard all connected to the raspberry pi so that we can use it independently from the laptop.</li>
</ul>
<h3 id="7-connect-the-rpi3-to-the-laptop-using-ethernet-cable">7. Connect the rpi3 to the laptop using ethernet cable.</h3>
<h3 id="8-put-the-sd-card-into-the-rpi3">8. Put the SD card into the rpi3.</h3>
<h3 id="9-setup-a-shared-ethernet-connection-between-the-laptop-and-rpi-to-get-the-ip-address-of-rpi">9. Setup a shared ethernet connection between the laptop and rpi to get the IP address of rpi.</h3>
<p>In general, one of the main problems for connecting via ssh to the Raspberry Pi is to know the IP address of the device.
This is very simple with Raspbian OS; simply turn on the raspberry pi and edit configurations to enable ssh, often over wifi.</p>
<p>This is where the ethernet capabilities of the raspberry pi come in.</p>
<blockquote>
<p>Goal: To find syslog message <code class="language-plaintext highlighter-rouge">DHCPACK</code> acknowledgement and assignment of the IP address after setting up shared connection between raspberry pi and the laptop.</p>
</blockquote>
<blockquote>
<blockquote>
<p>Throughout this process, continually look at logs. Eventually we will see a message DHCPACK which will likely be preceded by several DHCP handshake related messages such as DHCP DISCOVER, REQUEST etc. The DHCPACK message will contain the IP address of the ethernet device, and we will then be able to ssh into it.</p>
</blockquote>
</blockquote>
<ul>
<li>
<ol>
<li>Tail the syslogs of the laptop. On Debian distributions, this is often <code class="language-plaintext highlighter-rouge">/var/log/syslog</code>. Since we are using Fedora, we’ll be using <code class="language-plaintext highlighter-rouge">systemd's</code> <code class="language-plaintext highlighter-rouge">journald</code> with the <code class="language-plaintext highlighter-rouge">journactl</code> command:
<ul>
<li><code class="language-plaintext highlighter-rouge">sudo journalctl -f</code></li>
<li>Keep this open in a terminal window.</li>
<li>You can also come up with a better solution like grepping logs, if you like, or piping output of stdout elsewhere.</li>
</ul>
</li>
</ol>
</li>
<li>
<ol>
<li>In a second terminal window, open up the NetworkManager.
<ul>
<li>Become familiar with existing devices prior to powering on the raspberry pi, by running <code class="language-plaintext highlighter-rouge">nmcli</code>.</li>
</ul>
</li>
</ol>
</li>
<li>
<ol>
<li>Power on the raspberry pi. Watch your system logs.
<ul>
<li>Syslogs will detail the raspberry pi’s <code class="language-plaintext highlighter-rouge">name</code>.</li>
</ul>
</li>
</ol>
</li>
<li>
<ol>
<li>Look for that <code class="language-plaintext highlighter-rouge">name</code> in NetworkManager <code class="language-plaintext highlighter-rouge">nmcli device</code>.
<ul>
<li>Using NetworkManager <code class="language-plaintext highlighter-rouge">nmcli</code>, set up shared connection for the ethernet device.</li>
<li>Setting up a shared connection is as simple as <code class="language-plaintext highlighter-rouge">nmcli connection add type ethernet ifname $ETHERNET_DEVICE_NAME ipv4.method shared con-name local</code></li>
<li><a href="https://fedoramagazine.org/internet-connection-sharing-networkmanager/">This is a good tutorial</a> for setting up a shared connection with NetworkManager.</li>
</ul>
</li>
</ol>
</li>
<li>
<ol>
<li>Once the connection is shared, syslogs will show a <code class="language-plaintext highlighter-rouge">DHCPACK</code> message acknowledging the ethernet device and its IP address. (You may need to power cycle the rpi to see this message, but it will happen).</li>
</ol>
</li>
</ul>
<h3 id="10-ssh-into-the-rpi-and-start-wpe-webkit">10. ssh into the rpi and start WPE WebKit.</h3>
<ul>
<li>Now that we have the IP address of the raspberry pi, we can ssh into it from the laptop: <code class="language-plaintext highlighter-rouge">ssh root@<RPI3_IP_ADDRESS></code>. (The default password is ‘root’. You can also add your user public key to /root/.ssh/authorized_keys on the pi. You can simplify this process by creating an overlay/root/.ssh/authorized_keys on your computer and by specifying the path to the overlay directory in the BR2_ROOTFS_OVERLAY config variable. That will copy everything in the overlay dir to the image.)</li>
<li>After that, export these env variables <code class="language-plaintext highlighter-rouge">WPE_BCMRPI_TOUCH=1</code> and <code class="language-plaintext highlighter-rouge">WPE_BCMRPI_CURSOR=1</code> to enable keyboard and mouse control.
<ul>
<li><em>Why:</em> Recall that generally WPE WebKit is for embedded devices, such as kioks, or set top boxes requiring control with a remote control or similar device or touch interaction. We are exporting these environment variables so that we can “test” WPE WebKit with our separate mouse and keyboard for our raspberry pi without the need for a touch screen or special hardware targets, or a Wayland compositor such as <code class="language-plaintext highlighter-rouge">weston</code>. If this piques your curiosity, please see the <a href="https://wpewebkit.org/about/faq.html#is-wayland-required-to-run-wpe%3F">WPE WebKit FAQ on Wayland</a>.</li>
</ul>
</li>
<li>Start WPE WebKit with <code class="language-plaintext highlighter-rouge">cog</code>: <code class="language-plaintext highlighter-rouge">cog "http://www.igalia.com/"</code></li>
<li>A browser will launch in the external monitor connected to the raspberry pi 3, and we can control the browser with the raspberry pi’s mouse and keyboard!</li>
</ul>
<p>That’s all for now. Feel free to reach out in the support channels for WPE <a href="https://matrix.to/#/#wpe:matrix.org">on Matrix</a>.</p>
<h1 id="wpes-frequently-asked-questions">WPE’s Frequently Asked Questions</h1>
<ul>
<li><a href="https://wpewebkit.org/about/faq.html">https://wpewebkit.org/about/faq.html</a></li>
</ul>
Amanda Falke