Lab 1: Programming your Board
Preface
This section covers the ins and outs of Linux installation.
Why Linux?
Many students ask, “Why do I need to install Linux?”. To put it simply, it is the de facto development environment for embedded and system development. If you want to be taken seriously as a developer, you will need to learn to use Linux expertly!
Unix and the C programming language have a unique and special relationship. In many ways, Unix can be seen as an operating system that was specifically designed for developing in C, and the C programming language likewise is the programming language that was specifically designed for Unix system programming. Unix itself is literally defined in terms of the C programming language; and Unix’s utilities, such as compilers, text editors, and build tools, are all designed around working with C–and to a lesser but equal extent, assembly.
In contrast, Windows was not built with any particular language in mind, nor was it designed to facilitate software development. While C and C++ can be used in Windows development, the system’s architecture is much more abstracted, and Windows lacks any tight integration with a development toolchain like that which Unix offers. Its lack of native support for many open-source development tools also means that working in Windows is a tedious and fraught endeavor using ported software and/or compatibility layers which introduce additional levels of complexity and opportunities for errors to arise. On top of this, as many developers are using Linux, it can be difficult to get help when something goes wrong.
Additionally, while MacOS is a Unix operating system, and provides some base-level compatibility with open-source development tools, it can also run into trouble. The core issue lies with MacOS’s outdated core utilities, its closed source, and its “walled garden” philosophy that limits developers’ access to the broader open-source ecosystem. MacOS lacks a built-in package management system, something that Linux has had for decades. Package managers provide seamless installation, updating, and management of dependencies and development tools. Third-party tools like Homebrew have emerged to fill this gap, but they are not tightly integrated with MacOS and often have a less diverse and up-to-date set of packages compared to Linux–owing to Linux’s special place in the open-source development community. Many software packages that are available on Linux also do not work on MacOS since they use features that are unique to Linux systems.
Overview of Linux Distributions
Linux itself is just the kernel, and must be bundled with other software packages in order to make a complete operating system. Different bundles are called distributions. Minimally, a distribution includes implementations of the core POSIX utilities, but also usually includes a package management system, a service manager, and often some sort of graphical environment.
Linux can currently be divided into six major families, primarily identified by their package management systems, and further grouped into subfamilies based around other features such as bundled desktop environments, and so on.
Debian
Arguably the most popular, Debian is focused on stability and ease of use. Many Linux distributions oriented towards non-technical users, such as Ubuntu, are based around Debian. Debian’s package manager is APT (Advance Package Tool) , with .deb
. Documentation is generally very beginner-focused.
Red-Hat
Red Hat Enterprise Linux (RHEL) is a commercially developed distribution aimed at enterprise server environments, which operates on a paid subscription model. RHEL’s free and open-source upstream is the community-driven Fedora, where development and experimentation happens. A free and open-source RHEL rebuild called CentOS is also available and widely used for servers and other systems with many users. RHEL uses the YUM (Yellowdog Update, Modified) or DNF (Dandified Yum) package managers, with .rpm
packages.
Arch
Arch is a minimalist rolling-release distribution that emphasizes simplicity, control, and a “do-it-yourself” ethos. A basic Arch installation includes only the Linux Kernel, the GNU binutils for system utilities, and the pacmam package manager. Users are free to install and configure their own desktop environments, and other system software, as they see fit. This makes Arch well-suited to power-users, but also those who want to learn Linux from the ground up. Arch is also well-regarded for its extensive and bleeding-edge package database, excellent and detailed documentation and large, active community which is oriented towards developers and experienced users. Several popular downstreams of Arch, such as Manjaro, provide users with a minimal desktop environment and additional software to skip the lengthy setup process that characterizes an Arch installation.
Slackware
Slackware is one of the oldest Linux distributions, and is noted primarily for its simplicity. Slackware does not have an official package manager, and packages are installed from source. Slackware is a very bare-bones system suitable only for advanced, technically savvy users who are interested in manual dependency management and hands-on system administration.
Gentoo
Gentoo is a source-based distribution which installs all software directly from source, optimized for a users’ particular hardware, and with a high degree of control over software’s compile-time configuration parameters thanks to its powerful package manager, Portage. Gentoo is characterized by its long build-times when installing software–in exchange for efficiency, performance, and fine-grained user control over their systems.
Choosing a Distribution
The choice of which distribution to use is a highly personal decision. For simplicity sake, the two main contenders for first-time Linux users are Ubuntu (a Debian derivative) and Manjaro (an Arch derivative). Ubuntu is specifically oriented towards beginners who are familiar with Windows desktop environments, and comes packaged with the GNOME desktop environment. It hides much of the system internals behind nice graphical interfaces, and users rarely need to use a command-line. Ubuntu is great for beginners, but can be frustrating for tech-savvy users who want unrestrained control over their systems. Due to its added complexity, it can be difficult to install unsupported software packages and access advanced features without breaking things.
On the other hand, Manjaro is oriented towards power users and developers that want the versatility and control of Arch without the fuss of setting up their installation. Manjaro publishes different images based around different desktop environments. In general, I recommend KDE Plasma over GNOME, since it has better performance and is oriented more towards developers; it also bundles fewer unnecessary software packages.
A good place to browse other popular distributions is distrowatch, which helps users find the exact distribution that fits their needs.
Installing Linux
For this lab, we have burned the Manjaro KDE Plasma and Ubuntu installation media to flash drives for you to use. You are also welcome to choose and install your own distribution, but beware that everything in the course is tested on Arch/Manjaro. If you already have Linux, great! Please help your classmates with their systems :)
This guide is written for Windows users.
Dealing with BitLocker
Before beginning, you must take into account whether BitLocker (Windows proprietary hard drive encryption) is enabled on your computer. You can check if this is the case in the Windows Control Panel, by searching for “BitLocker”. If BitLocker is enabled, as soon as you disable Secure Boot (in order to boot into another OS, like Linux), then Windows will require your BitLocker key to decrypt your drive.
Warning
If you do not know your BitLocker key, and you disable Secure Boot, you will lose all of your data!
You can find the BitLocker key for your drive by looking in the BitLocker settings on the Control Panel. It may also be tied to your Microsoft or Institutional account, and available after logging into those, should you lock yourself out of the computer. Make a copy of this key and keep it somewhere safe.
Every time you boot into Windows, you will need to enter your BitLocker key. If you want to avoid having to enter this key, you can disable BitLocker following these instructions. BitLocker secures your hard drive when the device is turned off. Normally when you boot up, the Trusted Platform Module (TPM) sends the key to Windows in plaintext, allowing the drive to be decrypted. If the TPM detects changes to the boot configuration, it will refuse, and Windows will ask for the key from you. BitLocker mostly protects against a physical attacker from accessing the contents of your powered down computer. However, when used with the TPM module to avoid having to enter a key on every boot, it can be easily compromised by a physical attacker.
Resizing Windows Partition (optional)
Linux needs a drive partition to boot from. You will need about 15 Gb of free space on your computer to make room for Linux. You will either need to shrink your Windows partition to make room for Linux, or you will need to supply an additional drive–a >16GB USB 3.0 drive will work.
Shrinking an existing Windows partition may be done either from within Windows, or from the Linux installer. Some feel that the Windows tool is safer because it was designed by Microsoft. However, it resizes the partition that Windows is actively booted from, and some feel that this introduces additional complexity and possibility of data corruption. The Linux installer’s partitioning tool will run from the removable USB media, and therefore has the benefit of resizing the disk while it is not in-use. Which to use is a personal choice, as both will achieve the same end goal. If you have a second hard drive or removable media, or wish to use the Linux installer’s tool then you can skip this step entirely.
Note
If you decide to leave BitLocker enabled, the drive can only be resized from within Windows.
Warning
Repartitioning can result in data corruption and data loss. Typically, repartitioning errors result in corruption of partition tables without affecting the actual file data, so that recovery is possible but not guaranteed. These types of issues can occur if the computer suddenly loses power during partitioning, or if there is a defect in the drive or existing file system corruption. Please back up any important data before continuing.
Shrinking Windows Partition from within Windows
Windows provides a utility for managing drive partitions, called the Disk Management utility, which you can find by searching in the Start Menu.

To resize a partition, right-click on it, and select Shrink Volume… from the context menu.

In the modal window, enter the amount of space to shrink, and select the Shrink button. A minimum of 15,000 MB is recommended for our purposes. You will be able to adjust partition sizes later if necessary.

Disable Secure Boot
Before you can boot the installation media, you must disable Secure Boot in your computer’s firmware. The exact way to go about this differs by manufacturer. You will need to search online for “how to enter UEFI settings [manufacturer]”. For example, on HP laptops, you might press ESC repeatedly on booting up the computer, during POST (Power on Self Test). In the UEFI menu, there should be a setting for Secure Boot, which must be disabled.

Warning
Disabling Secure Boot will trigger BitLocker to require an encryption key, if it is enabled.
Booting Installation Media
Depending on your UEFI boot order settings, your computer may boot directly into the USB flash drive if it inserted at power-on. Otherwise, you will need to access the Boot Menu after powering the computer on. How to enter the boot menu also varies by manufacturer, though typically involves pressing a particular function key (e.g. F9) as the computer performs POST. Search online for your particular laptop model. Select the USB flash drive containing the installation media from the list of options, and boot from it.

You will be presented with another boot menu called Ventoy. Ventoy is a helper program that allows us to place multiple different Linux ISOs on a single flash drive (normally you can have only one). Select Manjaro Linux and boot to the Manjaro ISO. You will then be taken through two additional boot menus. Select the default option for each menu.
There may be a long delay with a black screen while Manjaro boots up. You should now be presented with a desktop environment. In a short moment, an installer dialog will appear.
Installing Linux
For most of the installation steps, the default options are acceptable; you may need to manually select the correct time zone, or it might guess correctly. There is no need to connect to the internet during installation.
At the stage where the installer asks where to install Linux, you have two options.
If you want to resize an existing partition (e.g. Windows) and install Linux in the space that creates, select Install Alongside. Select the storage device from the drop-down menu at the top of the window. Ensure you are selecting the right device (Do not select the USB drive that the installer is on). On the bottom portion of the screen will be a diagram of the partitions on the drive. The top image shows the drive as it is now, and the bottom part will show how it will be after partitioning. You should see a Windows partition if you are installing alongside it on the same drive. If you shrunk the windows partition in an earlier step, there will be an empty space after it which you should select on the upper diagram. Otherwise, select the Windows partition on the upper diagram. In the lower diagram, the new partition will be shown in red. You may drag its border to resize it. If you previously resized the Windows partition, then you should allow it to take up all of the unformatted space. Otherwise, you may now select how much of the Windows partition should be reclaimed for the new Linux partition. Make it at least 15 GB.
Warning
You will be prompted once more to confirm the partitioning. Data loss is a very unlikely but possible when partitioning. Back up any important data, and ensure you computer is plugged in during partitioning steps. If you previously shrunk the Windows partition, the risk of data loss at this stage is basically 0, since you are just creating a new partition in empty space. Confirm that you have selected Install Alongside and not Replace a partition or Erase Disk!
Booting Linux
After installation completes, you should be able to boot into Linux. Power off the computer and remove the USB flash drive. If everything worked properly, you will automatically boot into Linux when you turn the computer on. Ensure that you have removed the USB flash drive, and confirm that there is no Install Manjaro icon in the corner of the desktop. The installation desktop and installed desktop look very similar!
Congratulations! You are now a Linux user 😎
Installing Required Packages
In order to complete your work in this class, you will need to install required packages. You will perform this task using the package manager, called pacman. First you must connect to the internet. In the bottom tray, a WiFi icon should be present from which you can select an appropriate network and enter your credentials.
Once you are connected to the internet, open a terminal (e.g. Konsole) and run the following commands,
$ sudo sed -i 's/^ParallelDownloads.*$/ParallelDownloads=100/' /etc/pacman.conf
$ sudo pacman -Syu --noconfirm avr-gcc avr-libc avr-gdb avrdude base-devel neovim wget bear
Next, create a new directory for the lab, and download the lab files from the web,
$ mkdir lab1 && cd lab1
Next, compile the program,
$ make
avr-gcc -g -Wall -O2 -mmcu=atmega32u4 -DF_CPU=8000000UL -c -o main.o main.c
avr-gcc -g -Wall -O2 -mmcu=atmega32u4 -DF_CPU=8000000UL -Wl,-Map,main.map -o main.elf main.o
avr-objdump -h -S main.elf > main.lst
avr-objcopy -j .text -j .data -O ihex main.elf main.hex
avr-objcopy -j .text -j .data -O binary main.elf main.bin
avr-objcopy -j .text -j .data -O srec main.elf main.srec
avr-objcopy -j .eeprom --change-section-lma .eeprom=0 -O ihex main.elf main_eeprom.hex
avr-objcopy: --change-section-lma .eeprom=0x0 never used
avr-objcopy -j .eeprom --change-section-lma .eeprom=0 -O binary main.elf main_eeprom.bin
avr-objcopy: --change-section-lma .eeprom=0x0 never used
avr-objcopy -j .eeprom --change-section-lma .eeprom=0 -O srec main.elf main_eeprom.srec
avr-objcopy: --change-section-lma .eeprom=0x0 never used
After it successfully compiles, program your board. Plug in your board (if not already), and press the reset button on the board so that the “Boot” LED is slowly pulsing. You have ~9 seconds to complete the next step,
$ make program
sudo avrdude -c avr109 -p m32u4 -P /dev/ttyACM0 -e -U flash:w:main.hex -v
Avrdude version 8.0
Copyright see https://github.com/avrdudes/avrdude/blob/main/AUTHORS
System wide configuration file is /etc/avrdude.conf
User configuration file /root/.avrduderc does not exist
Using port : /dev/ttyACM0
Using programmer : avr109
AVR part : ATmega32U4
Programming modes : SPM, ISP, HVPP, JTAG
Programmer type : butterfly
Description : Atmel bootloader (AVR109, AVR911)
connecting to programmer: .
Programmer id = LUFACDC; type = S
Software version = 1.0; no hardware version given
programmer supports auto addr increment
programmer supports buffered memory access with buffersize=128 bytes
Devcode selected: 0x44
AVR device initialized and ready to accept instructions
Device signature = 1E 95 87 (ATmega32U4)
Erased chip
Reading 246 bytes for flash from input file main.hex
in 1 section [0, 0xf5]: 2 pages and 10 pad bytes
Writing 246 bytes to flash
Writing | ################################################## | 100% 0.02 s
Reading | ################################################## | 100% 0.00 s
246 bytes of flash verified
Avrdude done. Thank you.
Note
If you see the following error on programming,
$ make program
sudo avrdude -c avr109 -p m32u4 -P /dev/ttyACM0 -e -U flash:w:main.hex -v
Avrdude version 8.0
Copyright see https://github.com/avrdudes/avrdude/blob/main/AUTHORS
System wide configuration file is /etc/avrdude.conf
User configuration file /root/.avrduderc does not exist
Using port : /dev/ttyACM0
Using programmer : avr109
OS error: cannot open port /dev/ttyACM0: No such file or directory
Error: unable to open port /dev/ttyACM0 for programmer avr109
Avrdude done. Thank you.
make: *** [makefile:28: program] Error 1
Try restarting your computer and doing this step again. Sometimes the drivers seem a bit buggy. If that doesn’t fix it, you board may need to be reflashed. Talk to a TA.