SAM9X60-EK Evaluation Kit - Fast Boot Demonstration

Last modified by Microchip on 2024/06/20 12:44

Introduction

Booting an embedded Linux® system quickly is crucial for time-critical applications and significantly improves the user experience. This training topic gives some essential tips and techniques to achieve a quick boot on Microchip microprocessors (MPUs).

In this training, you will learn how to launch an Ensemble Graphics Toolkit (EGT) GUI-based application on a Microchip MPU running Linux in under 3 seconds.

Note:

Ensemble Graphics Toolkit (EGT) is a C++ based graphical Linux toolkit for Microchip microprocessors. For more information, visit the Microchip Technology Ensemble Graphics Toolkit website.

Summary of Steps

  • Minimize Boot Time
  • Minimize Linux Kernel Load and Startup Time
  • Minimize Application Startup Time
  • Prepare SD Memory Card
  • Fast Boot EGT Application from SD Memory Card

Note:

In this tutorial, you may either:

  1. Download and build the individual files as instructed, or
  2. Download the binary files necessary to flash an SD Memory Card.

Prerequisites

Hardware

You will use the SAM9X60-EK Evaluation Kit and a TM5000 High-Performance WVGA Display Module with maXTouch® Technology.

Refer to "SAM9X60-EK - Attaching the TM5000 WVGA Display" for instructions on how to assemble the LCD display onto the SAM9X60-EK.

SAM9X60-EK and WVGA Display Module

Back to top

Minimize Boot Time

In this section, you will download, configure, and build the second-stage bootloader, at91bootstrap, for fast booting.

Note:

For more in depth information about at91bootstrap, see at91bootstrap – Second Stage Bootloader

Create project directory:

Name your project directory fastboot.​

$ mkdir fastboot

Download at91bootstrap from the linux4sam remote repository in GitHub:

$ cd ~/fastboot
$ git clone git://github.com/linux4sam/at91bootstrap.git

Note:

When you git clone from a remote repository, you are creating a copy on your host computer’s project directory (also known to git as the working directory or local directory).


Configure using sam9x60eksd_linux_image_dt_defconfig:

Once you have cloned at91bootstrap to your project directory, you can configure the build. In this step, you will use a default configuration file, sam9x60eksd_linux_image_dt_defconfig, located in the ~/fastboot/at91bootstrap/board/ directory. This will configure the at91bootstrap (second-stage bootloader) to load the Linux kernel directly, thereby eliminating U-Boot (third-stage bootloader) from the boot sequence.

Note:

The config files are annotated with the choice of external boot memory. In this case, we choose to boot at91bootstrap from the SD Memory Card.

  • sd – SD Memory Card.
    The default configuration files are also annotated with the choice of what at91bootstrap will load next, either a third-stage bootloader (uboot) and/or an application (linux_image_dt). Here we choose to load the Linux kernel
  • linux_image_dt– Linux kernel and Device Tree.

Change the directory to the ~/fastboot/at91bootstrap folder and begin the configuration process:​

$ cd ~/fastboot/at91bootstrap
$ make sam9x60eksd_linux_image_dt_defconfig

Customize the at91bootstrap configuration to minimize boot time.

To customize the default configuration settings, use menuconfig. Menuconfig allows you to view the default configuration and make the required changes.

$ make menuconfig

fat91bootstrap Configuration Window

Observe that the Board Type (sam9x60ek) ---> has been selected.

Highlight Image Loading Strategy and observe that Support loading Linux directly has been selected.

Image Loading Strategy

Highlight [ ] Debug Support from the main menu and de-select it by pressing <N>.
Highlight Hardware Initialization Options ---> and press Enter.

De-select Display banner option by pressing <N>. Select <Exit>.

Hardware Initialization Options: deselect 'Display Banner'

Highlight Slow Clock Configuration Options ---> and press Enter.

Highlight Select slow clock configuration profile and change the setting to Use Internal RC oscillator as a source of slow clock.

Switching the slow clock source to the internal oscillator will eliminate the settling time required by the external crystal (which is selected by default). This will reduce boot time by almost one second.

Slow Clock Config: select internal RC option

You may exit menuconfig by repeatedly typing ESC-ESC until it closes. Save changes before exiting.

Build at91bootstrap.

Now that you have made all the configuration changes to reduce boot time, you can build at91bootstrap.

​$ make ARCH=arm CROSS_COMPILE=<path_to>/<cross_compiler>

Alert!

A working cross-toolchain for an Arm-based MPU target is required to build at91bootstrap.

Alert!

Ensure you set the CROSS_COMPILE=<path_to>/<cross_compiler> and ARCH=arm environment variables.

For example, if your cross-compiler executable is arm-linux-gcc then CROSS_COMPILE=<path_to>/arm-linux-

A second method is you may include these as command variables. For example:

$ make ARCH=arm CROSS_COMPILE=<path_to>/<cross_compiler>

The resulting binary images will be found in the at91bootstrap/binaries directory. The at91bootstrap.bin image will be used in a later section.

Note:

In this training, you may either:

  1. Download and build the individual files as instructed, or
  2. Download the binary files necessary to flash an SD Memory Card.

Back to Top


Minimizing Linux Kernel Load and Startup Time

Minimize Boot Time by limiting subsystems loaded

The Linux kernel load and startup time can be drastically reduced by configuring only the necessary peripherals and subsystems required by the Ensemble Graphics Toolkit (EGT) application. Therefore, from the SAM9X60 default device tree, you will disable all the peripherals that are not used by the EGT application. You will also disable them from the kernel configuration. The fewer subsystems and drivers the Kernel must initialize, the faster it will boot. Finally, you will add support for the LCD display.

Get linux-at91.

Download linux-at91 from the Microchip GitHub repository.

$ cd fastboot
$ git clone https://github.com/linux4sam/linux-at91.git -b linux4sam-2020.04

Open device tree file and disable all unused peripherals.

To make changes to the device tree, open the at91-sam9x60-ek.dts file using a text editor of your choice.

$ cd linux-at91/arch/arm/boot/dts
$ vi at91-sam9x60ek.dts

Now you can edit the *.dts file.

Add the following bold line:

{
    model = "Microchip SAM9X60-EK";
    compatible = "microchip,sam9x60ek",
                 "microchip,sam9x60", "atmel,at91sam9";
. . .
. . .
chosen {
    **bootargs="root=/dev/mmcblk0p2 rw rootwait loglevel=0";**
    stdout-path = "serial0:115200n8";
};

The loglevel is set to 0 which indicates minimal kernel debug messages and only the ones with utmost priority.

Change the status from “okay” to “disable” for the following peripherals: adc, can0, can1, classd, dbgu, flx4, flx5, flx6, i2s, macb0, pwm0, sdmmc1, qspi, usb0, usb1, usb2, isi.

&adc {
       vddana-supply = <&vdd1_3v3>;                                         
       vref-supply = <&vdd1_3v3>;                                                    
       pinctrl-names = "default";                                                          
       pinctrl-0 =
               <&pinctrl_adc_default &pinctrl_adtrg_default>;                          
       status = "disabled";
};

. . .
. . .

&can0 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_can0_rx_tx>;
        status = "disabled"; /* Conflict with dbgu. */
};
&can1 {                                                                                     
        pinctrl-names = "default";                                                          
        pinctrl-0 = <&pinctrl_can1_rx_tx>;                                                  
        status = "disabled";                                                                
};

&classd {                                                                                   
          pinctrl-names = "default";                                                          
          pinctrl-0 = <&pinctrl_classd_default>;                                              
          atmel,pwm-type = "diff";                                                            
          atmel,non-overlap-time = <10>;                                                      
          status = "disabled";
};     
. . .
. . .

&flx5 {                                                                                     
          atmel,flexcom-mode = <atmel_flexcom_mode_usart>;                                        
          status = "disabled";
. . .
. . .

&flx6 {                                                                                     
          atmel,flexcom-mode = <atmel_flexcom_mode_twi>;
          status = “disabled”;
. . .
. . .

&macb0 {
        phy-mode = "rmii";
        #address-cells = <1>;
        #size-cells = <0>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_macb0_rmii>;
        status = "disabled";
. . .
. . .

&sdmmc1 {
        bus-width = <4>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_sdmmc1_default>;
        no-1-8-v;
        non-removable;
        status = "disabled"; /* Conflict with flx4. */
};

&qspi {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_qspi>;
        status = "disabled"; /* Conflict with i2s. */
. . .
. . .

&usb0 {
        atmel,vbus-gpio = <&pioB 16 GPIO_ACTIVE_HIGH>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_usba_vbus>;
        status = "disabled";
};

&usb1 {
        num-ports = <3>;
        atmel,vbus-gpio = <0
                           &pioD 15 GPIO_ACTIVE_HIGH
                           &pioD 16 GPIO_ACTIVE_HIGH>;
        status = "disabled";
};

&usb2 {
        status = "disabled";
};   
. . .
. . .

&watchdog {
        status = "okay";
}; /*End of at91-sam9x60ek.dts file*/

Add support for the pda5 display in the device tree file at the end.

Note:

Refer to dt-overlay-at91 from the linux4sam repository in GitHub for the PDA5 screen support for the SAM9X60-EK.

&watchdog {
        status = "okay";
};

/* Support for pda5 */
&i2c0 {
        dmas = <0>, <0>;
        #address-cells = <1>;
        #size-cells = <0>;

        qt1070: keyboard@1b {
                compatible = "qt1070";
                reg = <0x1b>;
                interrupt-parent = <&pioB>;
                interrupts = <17 0x0>;
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_qt1070_irq>;
        };

        mxt: atmel_mxt_ts@4a {
                compatible = "atmel,atmel_mxt_ts";
                reg = <0x4a>;
                interrupt-parent = <&pioC>;
                interrupts = <25 0x8>;
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_mxt_irq>;
                wakeup-source;
        };
};

&hlcdc {
        status = "okay";

        hlcdc-display-controller {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_lcd_base &pinctrl_lcd_rgb888>;
                port@0 {
                        #address-cells = <1>;
                        #size-cells = <0>;
                        hlcdc_panel_output: endpoint@0 {
                                reg = <0>;
                                remote-endpoint = <&panel_input>;
                        };
                };
        };

        hlcdc_pwm: hlcdc-pwm {
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_lcd_pwm>;
        };
};

&gpu {
        status = "okay";
};

&pinctrl {
        qt1070 {
                pinctrl_qt1070_irq: qt1070_irq {
                        atmel,pins = <at91_piob 17="" at91_periph_gpio="" at91_pinctrl_pull_up_deglitch="">;
                };
        };

        mxt {
                pinctrl_mxt_irq: mxt_irq {
                        atmel,pins = <at91_pioc 25="" at91_periph_gpio="" at91_pinctrl_pull_up_deglitch="">;
                };
        };

        lcd {
                pinctrl_lcd_base: lcd-base-0 {
                        atmel,pins = <at91_pioc 27="" at91_periph_a="" at91_pinctrl_none="" *="" lcdvsync="" at91_pioc="" 28="" lcdhsync="" 24="" lcddisp="" 29="" lcdden="" 30="">;    /* LCDPCK */
                };

                pinctrl_lcd_rgb888: lcd-rgb-3 {
                        atmel,pins = <at91_pioc 0="" at91_periph_a="" at91_pinctrl_none="" *="" lcdd0="" pin="" at91_pioc="" 1="" lcdd1="" 2="" lcdd2="" 3="" lcdd3="" 4="" lcdd4="" 5="" lcdd5="" 6="" lcdd6="" 7="" lcdd7="" 8="" lcdd8="" 9="" lcdd9="" 10="" lcdd10="" 11="" lcdd11="" 12="" lcdd12="" 13="" lcdd13="" 14="" lcdd14="" 15="" lcdd15="" 16="" lcdd16="" 17="" lcdd17="" 18="" lcdd18="" 19="" lcdd19="" 20="" lcdd20="" 21="" lcdd21="" 22="" lcdd22="" 23="">;    /* LCDD23 pin */
                };

                pinctrl_lcd_pwm: lcd_pwm {
                        atmel,pins = <at91_pioc 26="" at91_periph_a="" at91_pinctrl_none="">;
                };
        };
};

&{/} {
    model = "Microchip SAM9X60-EK TM5000";

    backlight: backlight {
        compatible = "pwm-backlight";
        pwms = <&hlcdc_pwm 0 50000 0>;
        brightness-levels = <0 4 8 16 32 64 128 255>;
        default-brightness-level = <0>;
        power-supply = <&bl_reg>;
        status = "okay";
    };

    bl_reg: backlight_regulator {
        compatible = "regulator-fixed";
        regulator-name = "backlight-power-supply";
        regulator-min-microvolt = <5000000>;
        regulator-max-microvolt = <5000000>;
        status = "okay";
    };

    panel: panel {
        compatible = "pda,91-00156-a0", "simple-panel";
        backlight = <&backlight>;
        power-supply = <&panel_reg>;
        #address-cells = <1>;
        #size-cells = <0>;
        status = "okay";

        port@0 {
            reg = <0>;
            #address-cells = <1>;
            #size-cells = <0>;

            panel_input: endpoint@0 {
                reg = <0>;
                remote-endpoint = <&hlcdc_panel_output>;
            };
        };
    };

    panel_reg: panel_regulator {
        compatible = "regulator-fixed";
        regulator-name = "panel-power-supply";
        regulator-min-microvolt = <3300000>;
        regulator-max-microvolt = <3300000>;
        status = "okay";
    };
};

&isi {
        status = "disabled";
};  
/* End of pda5 support */  
/* End of at91-sam9x60ek.dts file */
Save and exit the file.

Disable peripherals from the kernel configuration.

Make the following changes to the kernel configurations by running menuconfig.​

$ cd ~/fastboot/linux-at91/
$ make at91_dt_defconfig ARCH=arm
$ make menuconfig

Alert!

Ensure you set the CROSS_COMPILE=<path_to>/<cross_compiler> and ARCH=arm environment variables.

For example, if your cross-compiler executable is arm-linux-gcc then CROSS_COMPILE=<path_to>/arm-linux-

A second method is you may include these as command variables. For example: $ make ARCH=arm CROSS_COMPILE=<path_to>/<cross_compiler>

Navigate to Networking Support and de-select it by pressing <N>.

Kernel Configuration Network Support

Highlight Device Drivers ---> and press Enter.

Navigate to each of the following unused peripherals and exclude them by pressing <N>.

  • Memory Technology device (MTD) support
  • Block devices
  • SCSI Device support
  • SPI support
  • PPS support
  • Hardware Monitoring support
  • Multimedia support
  • Sound card support
  • USB support
  • Staging drivers
  • Industrial I/O support

Kernel Configuration Device Drivers page 1

Kernel Configuration Device Drivers page 2

Kernel Configuration Device Drivers page 3

Exit menuconfig by repeatedly typing ESC-ESC until it closes. Save changes before exiting.

Build linux-at91.

Run the make command along with ARCH and CROSS_COMPILE variables.​

$ cd fastboot/linux-at91
$ make ARCH=arm CROSS_COMPILE=<path_to>/<cross_compiler>

Alert!

A working cross-toolchain for an Arm-based MPU target is required to build linux-at91.

Alert!

Ensure you set the CROSS_COMPILE=<path_to>/<cross_compiler> and ARCH=arm environment variables.

For example, if your cross-compiler executable is arm-linux-gcc then CROSS_COMPILE=<path_to>/arm-linux-

A second method is that you may include these as command variables. For example: $ make ARCH=arm CROSS_COMPILE=<path_to>/<cross_compiler>

The resulting device tree image is linux-at91/arch/arm/boot/dts/at91-sam9x60ek.dtb and the kernel image is linux-at91/arch/arm/boot/zImage.

Note:

In this training, you may either:

  1. Download and build the individual files as instructed, or
  2. Download the binary files necessary to Flash an SD Memory Card.

Back to top


Minimize Application Startup Time

The Linux kernel loads an init script that loads other services and applications. To minimize boot time, you will replace the standard init script with a minimal script.

The minimal script performs the following:

  • Mounts /sysfs, which is needed to control the backlight brightness from within the application.
  • Loads the final application, which is a basic automotive dashboard graphical display developed using the Ensemble Graphics Toolkit (EGT).

The application is compiled as a static executable. All the images, logos, and resources are compiled directly into the application and statically linked to it. Therefore, the resources are immediately available and mapped into the application’s address space.

Create Custom init script.

Create an init file and open using a text editor of your choice.​

$ cd ~/fastboot
$ vi init

Copy the following lines.

#!/bin/sh

mount -t sysfs none /sys
/usr/bin/egt_dashboard_fastboot
exec /bin/sh
Save the file and exit.

Change the init script to executable.​

$ cd ~/fastboot
$ chmod +x init

Download Ensemble Graphics Toolkit (EGT) application.

Download the EGT application, egt_dashboard_fastboot, to your ~/fastboot directory and change the image to an executable.

$ cd ~/fastboot
$ chmod +x egt_dashboard_fastboot

You will be copying the executable init and egt_dashboard_fastboot files to the Root File System (RootFS) of final image.

Note:
In this training topic you may either:

  1. Download and build the individual files as instructed, or
  2. Download the binary files necessary to flash an SD Memory Card.

Back to top


Preparing SD Memory Card Image

In this section, you will download a demonstration image from the Linux4SAM website for the purpose of using the Root File System on the image. You will flash the image to an SD Memory Card and delete the files in the BOOT partition. Finally, you will copy the at91bootstrap.binat91-sam9x60ek.dtb, and zImage files that you created in the previous section.

Download the SAM9X60-EK demonstration image from the Linux4SAM website.

The latest demonstration images for the SAM9X60-EK are available on the Linux4SAM website.

There you will find three sets of images created from one of three Build Systems:

  • The Yocto Project
  • Buildroot
  • OpenWRT

Choose the Buildroot based demo image with graphics support: linux4sam-buildroot-sam9x60ek-graphics-X.Y.img.bz2 where X.Y is the version number (X is the year and Y is the month of release).

Linux4SAM Demo Archives


Flash the demo image to the SD Memory Card.

Insert the SD Memory Card into a Linux desktop computer.

Delete the files in the BOOT(FAT32) partition.

Note:

In this training topic, you may either:

  1. Download and build the individual files as instructed, or
  2. Download the binary files necessary to flash an SD Memory Card.

Write binary files, which were created in the previous sections to the BOOT partition of the SD memory card.

Copy the at91bootrap.bin file.​

$ cd ~/fastboot/at91bootstrap/binaries
$ cp at91bootstrap.bin /media/<username>/<partion_name>/boot.bin

Copy the at91-sam9x60ek.dtb and zImage files.​

$ cd ~/fastboot/linux-at91/arch/arm/boot/dts/
$ cp at91-sam9x60ek.dtb /media/<username>/<partion_name>/at91-sam9x60ek.dtb​
$ cd ~/fastboot/linux-at91/arch/arm/boot/
$ cp zImage /media/<username>/<partion_name>/zImage

Now you have an SD Memory Card with the bootloader image (boot.bin), Linux kernel device tree (at91-sam9x60ek.dtb), and the kernel (zImage) in the BOOT partition. You also have the Root File System in the ROOTFS partition of the SD card.


Copy init and egt_dashboard_fastboot images to the RootFS partition of SD card.​

$ cd ~/fastboot
$ sudo cp –p init /media/<username>/ROOTFS/sbin/init
$ sudo cp egt_dashboard_fastboot /media/<username>/ROOTFS/usr/bin/

Memory Map of SD card

Remove the SD Memory Card from the Linux computer. You have now created a bootable Linux system image on the SD Memory Card.

Note that there are no u-boot images on the SD Memory Card. Recall that you configured and built at91bootstrap to load the Linux kernel directly. This will reduce boot time.

Back to top


Fast Boot from SD Memory Card

The SAM9X60-EK can be powered by one of two methods:

  • J1: An external power jack to supply +5 VDC via a 2.1 mm center-positive plug
  • J7: Powered through the USB Micro-B connector USB port A

Insert the SD card to slot J4 on the SAM9X60-EK target board.

SD card slot on SAM9X60-EK



Press the RESET push button SW3 (nRST).

SAM9X60-EK booted and running EGT demo

Congratulations! You have reduced the boot time of an embedded Linux system with an Ensemble Graphics Toolkit (EGT) application up and running!

Back to top


Summary

In this training, you changed the standard Linux boot process on the Microchip Microprocessors to reduce the boot time.

  • You configured and built at91bootstrap to load the Linux kernel directly.
  • You removed all subsystems and kernel drivers that are not used by the final application.
  • You used a pre-built RootFS on the SD card and replaced the standard init script with a minimal script that just loads the sysfs and EGT application.
  • The final application is an EGT Dashboard graphical demo on a Microchip PDA5 touchscreen.

The result is a fast boot of the EGT application in less than three seconds on cold reset!

Back to top

Learn More

Back to top