Bar
SpaceWire UK
Specialist providers of VHDL Intellectual Property & Design Services
BarBarBarBar
Tutorial
Missing Image!
Part 8 - Enable Petalinux webserver & create basic website to serve

Introduction

This tutorial details the steps required to enable the PetaLinux webserver and create an application to install the files required to form a static & dynamic website.

Aims

The aims of this tutorial are as follows :-

    Part 1 - Project Setup

    1. Setup environment
    2. Change present working directory

    Part 2 - Enable existing application

    1. Enable webserver

    Part 3 - Create installer application

    1. Create installer application
    2. Create static website
    3. Modify BitBake recipe

    Part 4 - Build & package PetaLinux

    1. Build PetaLinux
    2. Package PetaLinux

    Part 5 - Hardware Deployment

    1. Setup Zedboard hardware
    2. Launch MiniCom terminal emulator
    3. Run PetaLinux on Zedboard via JTAG
    4. Check everything is working as expected

    Part 6 - Revision Control

    1. Commit to repository

    Part 7 - Add dynamic server-side elements to website

    1. Create dynamic (server side) website
    2. Modify BitBake recipe
    3. Build, package & deploy project on Zedboard
    4. Check everything is working as expected

    Part 8 - Revision Control

    1. Commit to repository

    Part 9 - Add dynamic client-side elements to website

    1. Create dynamic (client side) website
    2. Modify BitBake recipe
    3. Build, package & deploy project on Zedboard
    4. Check everything is working as expected

    Part 10 - Revision Control

    1. Commit to repository

    Part 11 - Quickstart

    1. Obtain tutorial files from Bitbucket, create & build project, deploy on Zedboard
    #### Part 1 - Project Setup ####

    1. Setup environment

    Setup Xilinx design environment for the 2021.2 toolset.
    steve@Desktop:~$ xilinx
    Xilinx tools available tools at /opt/Xilinx :-
    1) 2021.2 - Vivado - SDK - Vitis - PetaLinux
    0) Exit
    Please select tools required or exit : 1

    Tools are as follows :-
    vivado @ /opt/Xilinx/Vivado/2021.2/bin/vivado
    vitis @ /opt/Xilinx/Vitis/2021.2/bin/vitis
    petalinux-build @ /opt/Xilinx/PetaLinux/2021.2/tool/tools/common/petalinux/bin/petalinux-build

    2. Change present working directory

    Change the present working directory to be the project directory.
    steve@Desktop:~$ cd ~/projects/zedboard_linux/os/petalinux
    #### Part 2 - Enable existing application ####

    3. Enable webserver

    Launch the PetaLinux configuration tool.
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ petalinux-config -c rootfs
    Navigate the menu selecting Filesystem Packages » base » busybox, enable busybox-httpd and then save the configuration and exit the tool. Missing Image!
    #### Part 3 - Create installer application ####

    4. Create installer application

    Create a new auto-enabled installer application.
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ petalinux-create --type apps --template install --name website --enable
    Examine the file structure of the newly created installer application.
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ tree project-spec/meta-user/recipes-apps/website
    project-spec/meta-user/recipes-apps/website
    ├── files
    │   └── website
    ├── README
    └── website.bb

    1 directory, 3 files

    website

    1. #!/bin/sh

    2. echo "Hello PetaLinux World"


    website.bb

    1. #
    2. # This file is the website recipe.
    3. #

    4. SUMMARY = "Simple website application"
    5. SECTION = "PETALINUX/apps"
    6. LICENSE = "MIT"
    7. LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"

    8. SRC_URI = "file://website \
    9.   "

    10. S = "${WORKDIR}"

    11. do_install() {
    12.        install -d ${D}/${bindir}
    13.        install -m 0755 ${S}/website ${D}/${bindir}
    14. }

    5. Create static website

    The website will consist of an index page that displays an image of the Zedboard hardware.

    Download the ZedBoard image file from Digilent into ~/Downloads. Rename & move this file into the website application area.
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ mv ~/Downloads/zedboard-2.png project-spec/meta-user/recipes-apps/website/files/zedboard.png
    Create a simple HTML index page and save this in the website application area.
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ subl project-spec/meta-user/recipes-apps/website/files/index.html

    index.html

    1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    5. <title>Zedboard webserver</title>
    6. </head>
    7. <body>
    8. Hello from your Zedboard webserver...
    9. <br>
    10. <img src="zedboard.png" alt="Missing Image!">
    11. </body>
    12. </html>

    6. Modify BitBake recipe

    Edit the BitBake recipe to remove the webserver entries that would allow installation of this application into /usr/bin. Add the entries for index.html & zedboard.jpg to allow installation of these into /srv/www.
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ subl project-spec/meta-user/recipes-apps/website/website.bb

    website.bb

    1. #
    2. # This file is the website recipe.
    3. #

    4. SUMMARY = "Simple website application"
    5. SECTION = "PETALINUX/apps"
    6. LICENSE = "MIT"
    7. LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"

    8. SRC_URI = "file://index.html"
    9. SRC_URI += "file://zedboard.png"

    10. FILES_${PN} += "/srv/www"

    11. S = "${WORKDIR}"

    12. do_install() {
    13.        install -d ${D}/srv/www
    14.        install -m 0644 ${S}/index.html ${D}/srv/www
    15.        install -d ${D}/srv/www
    16.        install -m 0644 ${S}/zedboard.png ${D}/srv/www
    17. }

    Remove the now unused webserver application.
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ rm project-spec/meta-user/recipes-apps/website/files/website
    #### Part 4 - Build & package PetaLinux ####

    7. Build PetaLinux

    Rebuild the project to include the updated files.
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ petalinux-build

    8. Package PetaLinux

    Package up the project ready for deployment.
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ petalinux-package --prebuilt --force
    #### Part 5 - Hardware Deployment ####

    9. Setup Zedboard hardware

    Connect up the hardware as follows :-
    1. Xubuntu PC USB ⇄ Zedboard USB JTAG/Debug
    2. Xubuntu PC USB ⇄ Zedboard USB UART
    3. Zedboard Ethernet ⇄ Router
    4. Xubuntu PC Ethenet ⇄ Router
    5. Router ⇄ Internet
    Missing Image! Set the boot mode jumpers on the Zedboard for JTAG. Missing Image! Power on the Zedboard.

    10. Launch MiniCom terminal emulator

    If not already running, open up a new terminal and launch the MiniCom terminal emulator.
    steve@Desktop:~$ minized

    Welcome to minicom 2.7.1

    OPTIONS: I18n
    Compiled on Dec 23 2019, 02:06:26.
    Port /dev/ttyACM0, 06:34:25

    Press CTRL-A Z for help on special keys

    11. Run PetaLinux on Zedboard via JTAG

    Power cycle the Zedboard and deploy the project via JTAG.
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ petalinux-boot --jtag --prebuilt 3

    12. Check everything is working as expected

    Access the webserver running on the Zedboard using a browser pointing at the Zedboard's IP address (192.168.2.87). All being well the following static webpage should be displayed. Missing Image!
    #### Part 6 - Revision Control ####

    13. Commit to repository

    Add and commit the new & updated files to the repository. Push the updated files but do not tag this release as it is a stepping stone.
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ git add project-spec/meta-user/recipes-apps/website
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ git commit -am "Enabled webserver application and created website installer application (static)."
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ git push
    #### Part 7 - Add dynamic server-side elements to website ####

    14. Create dynamic (server side) website

    The dynamic (server side) website will contain the same elements as the static website plus some extra system information that will be provided live when the page loads or is reloaded.

    Create a shell script like the one shown below that outputs what the previous index.html provided directly along with the additional information. This shell script will be called index.cgi and ultimately reside in /srv/www/cgi-bin.
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ mkdir project-spec/meta-user/recipes-apps/website/files/cgi-bin
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ subl project-spec/meta-user/recipes-apps/website/files/cgi-bin/index.cgi

    index.cgi

    1. #!/bin/sh

    2. # Output Header
    3. printf "Content-type: text/html\r\n\r\n"

    4. # Get information
    5. sys_host=$(hostname)
    6. sys_time=$(date)
    7. sys_load=$(awk '{print $1}' /proc/loadavg)
    8. sys_up=$(awk '{print $1}' /proc/uptime)
    9. cpu_model=$(grep model /proc/cpuinfo | cut -d : -f2 | tail -1 | sed 's/\s//')
    10. cpu_cores=$(grep -c ^processor /proc/cpuinfo)
    11. mem_total=$(free -m | awk 'NR==2{print $2}')
    12. mem_used=$(free -m | awk 'NR==2{print $3}')
    13. mem_free=$(free -m | awk 'NR==2{print $4}')
    14. net_mac=$(cat /sys/class/net/eth0/address)
    15. net_ip_loc=$(ip a | grep inet | grep -vw lo | grep -v inet6 | cut -d \/ -f1 | sed 's/[^0-9\.]*//g')
    16. net_ip_ext=$(wget -q -O- http://ipecho.net/plain)

    17. # Output HTML
    18. printf '<!DOCTYPE html>'
    19. printf '<html lang="en">'
    20. printf '<head>'
    21. printf '<meta http-equiv="content-type" content="text/html; charset=UTF-8">'
    22. printf '<title>Zedboard webserver</title>'
    23. printf '</head>'
    24. printf '<body>'
    25. printf 'Hello from your Zedboard webserver...'
    26. printf '<br>'
    27. printf '<img src="../zedboard.png" alt="Missing Image!">'

    28. printf '<br>System<br>'
    29. printf 'Honstname: %s<br>' "${sys_host}"
    30. printf 'Time: %s<br>' "${sys_time}"
    31. printf 'Uptime: %.2f seconds<br>' ${sys_up}

    32. printf '<br>CPU<br>'
    33. printf 'Model: %s<br>' "${cpu_model}"
    34. printf 'Cores: %d<br>' ${cpu_cores}
    35. printf 'Load: %.2f<br>' ${sys_load}

    36. printf '<br>Memory<br>'
    37. printf 'Total: %d Mb<br>' ${mem_total}
    38. printf 'Used: %d Mb<br>' ${mem_used}
    39. printf 'Free: %d Mb<br>' ${mem_free}

    40. printf '<br>Network<br>'
    41. printf 'MAC Address: %s<br>' "${net_mac}"
    42. printf 'Local IP: %s<br>' "${net_ip_loc}"
    43. printf 'External IP: %s<br>' "${net_ip_ext}"

    44. printf '</body>'
    45. printf '</html>'

    15. Modify BitBake recipe

    Modify the BitBake recipe to reflect the addition of the cgi-bin directory and index.cgi script, ensure the script entry sets the execution bit of the file. The webserver looks for the index file in /srv/www before looking in /srv/www/cgi-bin so the original index.html is temporarily renamed to take this out of the equation.
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ subl project-spec/meta-user/recipes-apps/website/website.bb

    website.bb

    1. #
    2. # This file is the website recipe.
    3. #

    4. SUMMARY = "Simple website application"
    5. SECTION = "PETALINUX/apps"
    6. LICENSE = "MIT"
    7. LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"

    8. SRC_URI = "file://index.html"
    9. SRC_URI += "file://zedboard.png"
    10. SRC_URI += "file://cgi-bin/index.cgi"

    11. FILES_${PN} += "/srv/www"

    12. S = "${WORKDIR}"

    13. do_install() {
    14.        install -d ${D}/srv/www
    15.        install -m 0644 ${S}/index.html ${D}/srv/www/index_original.html
    16.        install -d ${D}/srv/www
    17.        install -m 0644 ${S}/zedboard.png ${D}/srv/www
    18.        install -d ${D}/srv/www/cgi-bin
    19.        install -m 0755 ${S}/cgi-bin/index.cgi ${D}/srv/www/cgi-bin
    20. }

    16. Build, package & deploy project on Zedboard

    Rebuild the project to include the updated webserver, package up the project ready for deployment, power cycle the Zedboard and deploy the project via JTAG.
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ petalinux-build
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ petalinux-package --prebuilt --force
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ petalinux-boot --jtag --prebuilt 3

    17. Check everything is working as expected

    Access the webserver running on the Zedboard using a browser pointing at the Zedboard's IP address (192.168.2.87). All being well something akin to the following webpage should be displayed. Missing Image! Reload the page to refresh all the information displayed, most of which is static except for elements such as time, uptime, load & memory. The index.cgi page can be accessed directly via [Zedboard IP]/cgi-bin/index.cgi and the original index.html via [Zedboard IP]/index_original.html.
    #### Part 8 - Revision Control ####

    18. Commit to repository

    Add and commit the new & updated files to the repository. Push the updated files but do not tag this release as it is a stepping stone.
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ git add project-spec/meta-user/recipes-apps/website/files/cgi-bin
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ git commit -am "Added dynamic server-side elements to website application."
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ git push
    #### Part 9 - Add dynamic client-side elements to website ####

    19. Create dynamic (client side) website

    The dynamic (client side) website will contain the same elements as the previous dynamic (server side) website along with the ability to refresh the uptime element without reloading the whole page.

    Create a shell script that returns the uptime in seconds.
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ subl project-spec/meta-user/recipes-apps/website/files/cgi-bin/uptime.cgi

    uptime.cgi

    1. #!/bin/sh

    2. # Output Header
    3. printf "Content-type: text/html\r\n\r\n"

    4. # Output Command
    5. awk '{print $1}' /proc/uptime

    Create a Javascript file that contains the functions required to send & receive data to & from the webserver. Also add a function to enable & disable a timer.
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ subl project-spec/meta-user/recipes-apps/website/files/uptime.js

    uptime.js

    1. // Requests
    2. var uptime_req;
    3. var timer_req;

    4. // Receive data & update webpage accordingly
    5. function GotUptime() {
    6.   if (uptime_req.readyState == 4 && uptime_req.status == 200) {
    7.     txtObj = document.getElementById("uptime_text");
    8.     if (txtObj !== null) {
    9.       txtObj.innerHTML = uptime_req.responseText;
    10.     }
    11.   }
    12. }

    13. // Setup request and ask for data return
    14. function GetUpTime() {
    15.   if (window.XMLHttpRequest) {
    16.     uptime_req = new XMLHttpRequest();
    17.     uptime_req.abort();
    18.     uptime_req.onreadystatechange = GotUptime;
    19.     uptime_req.open("POST", "/cgi-bin/uptime.cgi", true);
    20.     uptime_req.send(null);
    21.   }
    22. }

    23. // Setup/Cancel timer request
    24. function SetTimeout(obj) {
    25.   clearInterval(timer_req);
    26.   var interval = obj.value;
    27.   if (interval > 0) {
    28.     timer_req = setInterval("GetUpTime()", 1000 * interval);
    29.   }
    30. }

    Modify the index.cgi webpage as follows :-
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ subl project-spec/meta-user/recipes-apps/website/files/cgi-bin/index.cgi

    index.cgi

    1. #!/bin/sh

    2. # Output Header
    3. printf "Content-type: text/html\r\n\r\n"

    4. # Get information
    5. sys_host=$(hostname)
    6. sys_time=$(date)
    7. sys_load=$(awk '{print $1}' /proc/loadavg)
    8. sys_up=$(awk '{print $1}' /proc/uptime)
    9. cpu_model=$(grep model /proc/cpuinfo | cut -d : -f2 | tail -1 | sed 's/\s//')
    10. cpu_cores=$(grep -c ^processor /proc/cpuinfo)
    11. mem_total=$(free -m | awk 'NR==2{print $2}')
    12. mem_used=$(free -m | awk 'NR==2{print $3}')
    13. mem_free=$(free -m | awk 'NR==2{print $4}')
    14. net_mac=$(cat /sys/class/net/eth0/address)
    15. net_ip_loc=$(ip a | grep inet | grep -vw lo | grep -v inet6 | cut -d \/ -f1 | sed 's/[^0-9\.]*//g')
    16. net_ip_ext=$(wget -q -O- http://ipecho.net/plain)

    17. # Output HTML
    18. printf '<!DOCTYPE html>'
    19. printf '<html lang="en">'
    20. printf '<head>'
    21. printf '<meta http-equiv="content-type" content="text/html; charset=UTF-8">'
    22. printf '<script src="../uptime.js"></script>';
    23. printf '<title>Zedboard webserver</title>'
    24. printf '</head>'
    25. printf '<body>'
    26. printf 'Hello from your Zedboard webserver...'
    27. printf '<br>'
    28. printf '<img src="../zedboard.png" alt="Missing Image!">'

    29. printf '<br>System<br>'
    30. printf 'Honstname: %s<br>' "${sys_host}"
    31. printf 'Time: %s<br>' "${sys_time}"
    32. printf 'Uptime: <span id="uptime_text">%.2f</span> seconds ' ${sys_up}
    33. printf '​<button onclick="GetUpTime()">Refresh</button>'
    34. printf '​ Auto : <select onchange="SetTimeout(this)">'
    35. printf '​<option value="0">Off</option>'
    36. printf '​<option value="1">1s</option>'
    37. printf '​<option value="5">5s</option>'
    38. printf '​</select><br>'

    39. printf '<br>CPU<br>'
    40. printf 'Model: %s<br>' "${cpu_model}"
    41. printf 'Cores: %d<br>' ${cpu_cores}
    42. printf 'Load: %.2f<br>' ${sys_load}

    43. printf '<br>Memory<br>'
    44. printf 'Total: %d Mb<br>' ${mem_total}
    45. printf 'Used: %d Mb<br>' ${mem_used}
    46. printf 'Free: %d Mb<br>' ${mem_free}

    47. printf '<br>Network<br>'
    48. printf 'MAC Address: %s<br>' "${net_mac}"
    49. printf 'Local IP: %s<br>' "${net_ip_loc}"
    50. printf 'External IP: %s<br>' "${net_ip_ext}"

    51. printf '</body>'
    52. printf '</html>'

    20. Modify BitBake recipe

    Modify the BitBake recipe to reflect the addition of the uptime.js include and uptime.cgi script, ensure the script entry sets the execution bit of the file.
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ subl project-spec/meta-user/recipes-apps/website/website.bb

    website.bb

    1. #
    2. # This file is the website recipe.
    3. #

    4. SUMMARY = "Simple website application"
    5. SECTION = "PETALINUX/apps"
    6. LICENSE = "MIT"
    7. LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"

    8. SRC_URI = "file://index.html"
    9. SRC_URI += "file://uptime.js"
    10. SRC_URI += "file://zedboard.png"
    11. SRC_URI += "file://cgi-bin/index.cgi"
    12. SRC_URI += "file://cgi-bin/uptime.cgi"

    13. FILES_${PN} += "/srv/www"

    14. S = "${WORKDIR}"

    15. do_install() {
    16.        install -d ${D}/srv/www
    17.        install -m 0644 ${S}/index.html ${D}/srv/www/index_original.html
    18.        install -d ${D}/srv/www
    19.        install -m 0644 ${S}/uptime.js ${D}/srv/www
    20.        install -d ${D}/srv/www
    21.        install -m 0644 ${S}/zedboard.png ${D}/srv/www
    22.        install -d ${D}/srv/www/cgi-bin
    23.        install -m 0755 ${S}/cgi-bin/index.cgi ${D}/srv/www/cgi-bin
    24.        install -d ${D}/srv/www/cgi-bin
    25.        install -m 0755 ${S}/cgi-bin/uptime.cgi ${D}/srv/www/cgi-bin
    26. }

    21. Build, package & deploy project on Zedboard

    Rebuild the project to include the updated files, package it up ready for deployment, power cycle the Zedboard and deploy via JTAG.
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ petalinux-build
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ petalinux-package --prebuilt --force
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ petalinux-boot --jtag --prebuilt 3

    22. Check everything is working as expected

    Access the webserver running on the Zedboard using a browser pointing at the Zedboard's IP address (192.168.2.87). All being well something akin to the following webpage should be displayed. Missing Image! Reload the page to refresh all the information displayed or click on the Refresh button to refresh only the uptime. Use the Auto dropdown to select the interval of an automatic uptime refresh.
    #### Part 10 - Revision Control ####

    23. Commit to repository

    Add and commit the new & updated files, create an annotated tag and push the commit & tag up to the remote repository.
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ git add project-spec/meta-user/recipes-apps/website/files/cgi-bin/uptime.cgi
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ git add project-spec/meta-user/recipes-apps/website/files/uptime.js
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ git commit -am "Added dynamic client-side elements to website application."
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ git tag -a v4.0 -m "PetaLinux, Peek/Poke, LED Runner & Webserver with XSA from zedboard_leds_switches v1.0"
    steve@Desktop:~/projects/zedboard_linux/os/petalinux$ git push
    #### Part 11 - Quickstart ####

    24. Obtain tutorial files from Bitbucket, create & build project, deploy on Zedboard

    The source files relating to this tutorial for the OS can be obtained from Bitbucket. The OS repository contains both PetaLinux and a local copy of the exported hardware (firmware).

    The instructions below assume that Part 1 - Installation of tools, setup of environment and creation of project area has been completed in full and that the environment has been setup as per 1. Setup environment. The root project area ~/projects should be present and contain the common project. The zedboard_linux projects should NOT be present. Adjust the commands below to suit if the above differs.

    Obtain OS source, build & deploy on Zedboard.
    steve@Desktop:~$ cd ~/projects
    steve@Desktop:~/projects$ git clone -b v4.0 https://bitbucket.org/spacewire_firmware/zedboard_linux
    steve@Desktop:~/projects$ cd zedboard_linux/os/petalinux
    Do something with the OS (if required) then perform the following steps :-
    1. Build PetaLinux
    2. Package PetaLinux
    3. Setup Zedboard hardware
    4. Launch MiniCom terminal emulator
    5. Run PetaLinux on Zedboard via JTAG
    6. Check everything is working as expected