Wireless Updates

Uncover our latest and greatest product updates
blogImage

How to Add Custom Profiles in Bluetooth - Part 1

OverviewThis article describes the procedure to add a custom Bluetooth profile for sharing the temperature and humidity data over Bluetooth. The article is split into two; the first part will brief on the Bluetooth technology and Bluetooth profiles while the second part gives details on the addition of custom Bluetooth GATT profile. We assume the reader has some knowledge on the Bluetooth technology, during writing of this article.[Brief overview of BluetoothAs we all know Bluetooth is a wireless communication technology, which is found in almost all the mobile phones. The range of these wireless communication medium is based on the Bluetooth device type. There are two types of Bluetooth devices, Single mode and Dual mode devices. Single mode Bluetooth devices are devices which either support BR/EDR or LE profiles. Dual mode devices support both BR/EDR and LE profiles. The range for BR/EDR devices is 10 meters and the range for LE devices is around 1-2 meters. The figure below shows the Bluetooth stack and the details of the stack are given as below.Software Layers in BluetoothAs we can see from the above figure, Bluetooth software stack is layered implementation. A brief overview of the layers of Bluetooth stack (seen in the above figure) are as below.Bluetooth RadioBluetooth Radio operates in the 2.4 GHz ISM band (same as the Wi-Fi, ZigBee etc.). It uses a frequency hopping mechanism with 79 channels to combat interference with other channels which operate in the same frequency spectrum. This layer is responsible for the following primary tasks:Transmission and Reception of packets over the airSupport appropriate power class of the device, for LE devices (power consumption is less)Baseband Controller (also referred to as the Link Controller)The Baseband controller performs the following major functions:Management of physical channels and linksManages frequency hopping for transmitting and receiving packetsManagement of formation of piconet and scatternetHandles packets formation for Bluetooth radio transmissionInquiry and Inquiry ScanConnection and Page ScanSecurity (including data encryption)Power management (including low power modes)Link ManagerThe Link Manager performs the functions of link setup and control. The LMP supports connection control (creation and removal of a connection), security (authentication, pairing, and encryption), informational requests (characteristics exchange), role switch, also handles logical transports, Quality of Service and link supervision.Host Controller Interface (HCI)The Host Controller Interface (HCI) provides uniform method for accessing the controller’s capabilities. The HCI layer provides an interface for the host to talk to the controller. The host sends HCI command packets to the controller and is asynchronously notified by the controller using HCI events. The LE controllers use a reduced set of HCI commands. There are four types of packets that can be sent on the HCI Interface.HCI Command Packet.HCI Asynchronous (ACL) Data Packet.HCI Synchronous Data Packet.HCI Event Packet.L2CAP layer (Logical Link Control and Adaptation Protocol)The L2CAP layer acts as an interface between the higher layer protocols and the lower layers. L2CAP provides the abstraction of channels to layers on top of it. Following are some of the features supported by the L2CAP layer:Fixed channel identifiersFragmentation and Defragmentation of dataMultiplexing and demultiplexing of various channels over a shared logical linkRFCOMMThe RFCOMM protocol layer is on top of the L2CAP layer. RFCOMM layer provides emulated RS-232 serial ports. The Bluetooth serial port profile is based on this protocol. It is used directly by many telephony related profiles to send AT commands, and used as transport layer for OBEX over Bluetooth. In the protocol stack, RFCOMM is bound to L2CAP.SDPSDP protocol layer is used to allow devices to discover what services are supported by each other, and what parameters to use to connect to them. SDP is used to determine which Bluetooth profiles are supported by the Bluetooth device (like headset profile, hands free profile, advanced audio distribution profile, etc.) and the protocol multiplexer settings needed to connect to each of them. Each service is identified by a Universally Unique Identifier (UUID), with official services (Bluetooth profiles) assigned a short form UUID (16 bits rather than the full 128). In the protocol stack, SDP is bound to L2CAP.OBEXObject exchange is a communications protocol that facilitates the exchange of binary objects between devices. It is adopted by the Bluetooth Special Interest Group. In Bluetooth, OBEX is used for many profiles that require simple data exchange. In the protocol stack, OBEX is bound to RFCOMM.ATTATT protocol is like SDP protocol, but specially adapted and simplified for Low Energy Bluetooth. It allows a client to read and/or write certain attributes exposed by the server in a non-complex, low-power friendly manner. In the protocol stack, ATT is bound to L2CAP.Profiles in BluetoothBluetooth devices need to support appropriate profiles, to be able to work together for accomplishing a given task. A profile defines a usage case. Profiles are the “services” offered by a device. For two devices to interoperate to complete a user task, both devices must implement a common profile. Profiles are definitions of possible applications and specify general behaviours that Bluetooth enabled devices use to communicate with other Bluetooth devices. Profiles build on the Bluetooth standard to more clearly define what kind of data a Bluetooth module is transmitting. The device’s application determines which profiles it must support, from hands-free capabilities to heart rate sensors to alerts and more.For two Bluetooth devices to be compatible, they must support the same profiles. Profiles are different for Bluetooth BR/EDR and LE implementations. Compatibility between BR/EDR and LE implementations requires a dual-mode controller on at least one device for interoperability. For BR/EDR, a wide range of adopted Bluetooth profiles describe many different common types of applications or use cases for devices. For Bluetooth LE, developers have the option of using a comprehensive set of adopted profiles, or use the Generic Attribute Profile (GATT) to create new profiles.Below is a list of some commonly used Bluetooth Profiles:Advanced Audio Distribution Profile (A2DP)Audio/Video Remote Control Profile (AVRCP)Generic Object Exchange Profile (GOEP)Human Interface Device Profile (HID)Personal Area Networking Profile (PAN)Serial Port Profile (SPP)Service Discovery Profile (SDAP)SIM Access Profile (SAP, SIM)Basic Imaging Profile (BIP)Basic Printing Profile (BPP)Device ID Profile (DID)Dial-up Networking Profile (DUN)File Transfer Profile (FTP)Generic Access Profile (GAP)Hands-Free Profile (HFP)Headset Profile (HSP)Object Push Profile (OPP)GATT (Generic Attribute profile)Unlike GAP which broadcasts one-to-many, GATT uses a one-to-one connection between the board (server) and the phone (client). GATT establishes in detail how to exchange all profile and user data over a BLE connection. GATT uses the Attribute Protocol (ATT) as its transport protocol to exchange data between devices. This data is organized hierarchically in sections called services, which group conceptually related pieces of user data called characteristics.The second part of the article will discuss in more detail the fundamental aspects of GATT and addition of custom profiles.

Aziro Marketing

blogImage

How To Add Custom Profiles In Bluetooth – Part 2

OverviewThis article is a continuation of the previous article, and gives a brief on adding a custom Bluetooth profile for sharing the temperature and humidity data over Bluetooth. This article also gives a brief description of the Bluetooth GATT profiles in Bluetooth.GATT Profiles in BluetoothGATT is an acronym for the Generic Attribute Profile, it is a specification regarding an aspect of Bluetooth-based wireless communication between devices and defines the way two Bluetooth Low Energy devices transfer data back and forth using concepts called Services and Characteristics. The GATT profile describes a use case, roles and general behaviours based on the GATT functionality. Services are collections of characteristics and relationships to other services that encapsulate the behaviour of part of a device. This also includes hierarchy of services, characteristics and attributes used in the attribute server.GATT uses ATT as the transport mechanism for discovering attributes of the remote devices and ATT provides services to the Generic Attribute Profile. An attribute is something that represents data. ATT protocol is designed to push or pull that data to or from a remote device. ATT protocol also supports setting notifications and indications so that the remote devices can be alerted when that data changes. The figure below shows GATT protocol stack.Figure 1: GATT protocol in LE protocol stackGATT profile as with any other profile follows the Client Server model. The GATT client corresponds to the ATT client, and sends requests to a server and receives responses from it. The GATT client does not know anything in advance about the server’s attributes, so it must first inquire about the presence and nature of those attributes by performing service discovery. After completing service discovery, it can then start reading and writing attributes found in the server. The GATT server corresponds to the ATT server, and it receives requests from a client and sends responses back. The GATT server is responsible for storing and making the user data available to the client, organized in attributes. Every BLE device must include at least a basic GATT server that can respond to client requests, even if only to return an error response. This article explains how to implement a custom profile in the server side.GATT follows a strict hierarchy to organize attributes in a manner to allow access and retrieval of information between client and server to follow a concise set of rules that together constitute the framework used by all GATT-based profiles. The following figure shows the data hierarchy introduced by GATT.Figure 2: Data hierarchy introduced by GATTAdding Custom ProfileCustom Bluetooth profile includes custom services and characteristics and can also include standard services and characteristics. In the following sections there is brief description on defining the service, characteristics, descriptors and UUIDs.In our case, we read temperature/humidity data from the DTH11 sensor device using the raspberry pi device (as show in the figure below). The sensor data read is transmitted over Bluetooth to the other system for processing with another device.Figure 3: Raspberry Pi connected to a DTH11 sensor and USB Bluetooth dongle Figure 4: RPi device acts as Server which collects the sensor data and sends it to the computer over BluetoothWe create a GATT based profile implementation in our use case, which consists of roles and which services each role implements. A service is comprised of one or more characteristics, and follows client server design pattern. We define a GATT based profile which will contain a description of the use case, the roles required to support the use case, the one or more services exposed which enable the use case as well as the definition of the server required to implement the use case.Defining Use Case – Temperature/Humidity sensor dataWe need to define what will be enabled and what won’t.The DTH11 sensor device will get the temperature and humidity sensor data, which will be processed by another device (client system). The format of the temperature data returned is a signed 8 bit integer.Defining ServicesA Service is a collection of one or more characteristics intended to work together to perform a function. When describing the characteristics within a service, the way in which those characteristics are utilized is defined. This includes defining properties as well as descriptors for each characteristic. The property metadata defines how the characteristic can be accessed and includes such capabilities as readable, writeable, broadcast and if authentication is required. The descriptors define metadata such as description and presentation information. A service may contain both mandatory and optional characteristics.The service definition for reading the room temperature and humidity is very simple. It only needs to use the two characteristic defined (Temperature and Humidity) above as mandatory and add the metadata describing how that characteristic can be utilized in the service. The service description is given below. The function gatt_service_add is used for adding the GATT based service.static gboolean register_temp_sensor_service(struct btd_adapter *adapter) { bt_uuid_t uuid; bt_uuid16_create(&uuid, TEMP_SENSOR_STATE_SVC_UUID); return gatt_service_add(adapter, GATT_PRIM_SVC_UUID, &uuid, /* temperature sensor state characteristic */ GATT_OPT_CHR_UUID16, TEMP_SENSOR_STATE_UUID, GATT_OPT_CHR_PROPS, GATT_CHR_PROP_READ | GATT_CHR_PROP_NOTIFY, GATT_OPT_CHR_VALUE_CB, ATTRIB_READ, temp_sensor_state_read, adapter, GATT_OPT_INVALID); }Defining CharacteristicsAfter defining the use case, we will define the characteristics, which are required for enabling this use case. A characteristic is a piece of data, a value, with metadata to describe the data of GATT based profile. Each GATT based profile exposes at least one service that exposes at least one characteristic; some will have many more. To define a characteristic for each service, we need to define:Data Value: The data value describes the type and the length of the data transferred. Supported data types include unsigned byte, signed byte, word, character string, and array.Property: The property describes how the data value is accessed. Available choices are Broadcast, Read, Write, WriteWithoutResponse, Notify, Indicate, SignedWrite, and WritableAuxiliaries.Permissions: Permissions describe the access permissions for the data. Permission settings are provided for Encryption, Authentication, and Authorization.UUID: The UUID value (128-bit) uniquely identifies the characteristicIn our case, the Data Value, Property, Permissions are passed as part of the gatt_service_add function call. The UUID is defined locally to identify the characteristic (for our case we are using 32-bit value to define the UUID)#define TEMP_SENSOR_STATE_SVC_UUID 0xB002 #define TEMP_SENSOR_STATE_UUID 0xB003 #define MANUFACTURER_SVC_UUID 0xB005 #define TEMPERATURE_UUID 0xB006Once the GATT based profile is defined, it can be compiled into the structure required by the device implementing the profile. A Characteristic is a fundamental building block used in the creation of GATT based profiles.Within the Value section itself, one or more fields are defined. Each field consists of a name which must be unique within that characteristic as well as the type of the data contained in the field and optional exponent definition.Since a suitable temperature and humidity characteristic has already been defined, these characteristics are included in the service.Defining ProfilesA Profile is a collection of one or more services intended to work together to enable a use case. The profile may contain both mandatory and optional services. However, a characteristic which is not part of a service may not be included in a profile.In both the “Obtaining the temperature in a room” and “Obtaining the humidity of the room” examples, the use case is fully defined by a single Service.Figure 5: Client and Server roles for Temperature and Humidity sensor and display the sameThe code implementation for the server side role for this profile is as below using BlueZ package./* *  BlueZ - Bluetooth protocol stack for Linux * *  Copyright (C) 2010  Nokia Corporation *  Copyright (C) 2010  Marcel Holtmann * * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA * * */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include "lib/bluetooth.h" #include "lib/sdp.h" #include "lib/uuid.h" #include "src/plugin.h" #include "src/adapter.h" #include "src/shared/util.h" #include "src/log.h" #include "attrib/gattrib.h" #include "attrib/gatt-service.h" #include "attrib/att.h" #include "attrib/gatt.h" #include "attrib/att-database.h" #include "src/attrib-server.h" /* Not defined as UUID128 */ #define OPCODES_SUPPORTED_UUID      0xB001 #define TEMP_SENSOR_STATE_SVC_UUID 0xB002 #define TEMP_SENSOR_STATE_UUID 0xB003 #define MANUFACTURER_SVC_UUID 0xB005 #define TEMPERATURE_UUID 0xB006 #define BLUETOOTH_SIG_UUID 0xB00B #define MANUFACTURER_NAME_UUID 0xB00C #define MANUFACTURER_SERIAL_UUID 0xB00D #define VENDOR_SPECIFIC_SVC_UUID 0xB00E #define VENDOR_SPECIFIC_TYPE_UUID 0xB00F struct temp_sensor_adapter { struct btd_adapter *adapter; GSList *sdp_handles; }; static GSList *adapters = NULL; static void temp_sensor_adapter_free(struct temp_sensor_adapter *gadapter) { while (gadapter->sdp_handles != NULL) { uint32_t handle = GPOINTER_TO_UINT(gadapter->sdp_handles->data); attrib_free_sdp(gadapter->adapter, handle); gadapter->sdp_handles = g_slist_remove(gadapter->sdp_handles, gadapter->sdp_handles->data); } if (gadapter->adapter != NULL) btd_adapter_unref(gadapter->adapter); g_free(gadapter); } static int adapter_cmp(gconstpointer a, gconstpointer b) { const struct temp_sensor_adapter *gatt_adapter = a; const struct btd_adapter *adapter = b; if (gatt_adapter->adapter == adapter) return 0; return -1; } static uint8_t temp_sensor_state_read(struct attribute *a,  struct btd_device *device, gpointer user_data) { struct btd_adapter *adapter = user_data; uint8_t value; value = 0x04; attrib_db_update(adapter, a->handle, NULL, &value, sizeof(value), NULL); return 0; } static gboolean register_temp_sensor_service(struct btd_adapter *adapter) { bt_uuid_t uuid; bt_uuid16_create(&uuid, TEMP_SENSOR_STATE_SVC_UUID); return gatt_service_add(adapter, GATT_PRIM_SVC_UUID, &uuid, /* TEMP_SENSOR state characteristic */ GATT_OPT_CHR_UUID16, TEMP_SENSOR_STATE_UUID, GATT_OPT_CHR_PROPS, GATT_CHR_PROP_READ | GATT_CHR_PROP_NOTIFY, GATT_OPT_CHR_VALUE_CB, ATTRIB_READ, temp_sensor_state_read, adapter, GATT_OPT_INVALID); } static void register_manuf1_service(struct temp_sensor_adapter *adapter, uint16_t range[2]) { const char *manufacturer_name1 = "DTH11 Temperature Sensor"; const char *serial1 = "11111-111-B"; uint16_t start_handle, h; const int svc_size = 5; uint8_t atval[256]; bt_uuid_t uuid; int len; bt_uuid16_create(&uuid, MANUFACTURER_SVC_UUID); start_handle = attrib_db_find_avail(adapter->adapter, &uuid, svc_size); if (start_handle == 0) { error("Not enough free handles to register service"); return; } DBG("start_handle=0x%04x", start_handle); h = start_handle; /* Secondary Service: Manufacturer Service */ bt_uuid16_create(&uuid, GATT_SND_SVC_UUID); put_le16(MANUFACTURER_SVC_UUID, &atval[0]); attrib_db_add(adapter->adapter, h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2); /* Manufacturer name characteristic definition */ bt_uuid16_create(&uuid, GATT_CHARAC_UUID); atval[0] = GATT_CHR_PROP_READ; put_le16(h + 1, &atval[1]); put_le16(MANUFACTURER_NAME_UUID, &atval[3]); attrib_db_add(adapter->adapter, h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5); /* Manufacturer name characteristic value */ bt_uuid16_create(&uuid, MANUFACTURER_NAME_UUID); len = strlen(manufacturer_name1); strncpy((char *) atval, manufacturer_name1, len); attrib_db_add(adapter->adapter, h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len); /* Manufacturer serial number characteristic */ bt_uuid16_create(&uuid, GATT_CHARAC_UUID); atval[0] = GATT_CHR_PROP_READ; put_le16(h + 1, &atval[1]); put_le16(MANUFACTURER_SERIAL_UUID, &atval[3]); attrib_db_add(adapter->adapter, h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5); /* Manufacturer serial number characteristic value */ bt_uuid16_create(&uuid, MANUFACTURER_SERIAL_UUID); len = strlen(serial1); strncpy((char *) atval, serial1, len); attrib_db_add(adapter->adapter, h, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len); g_assert(h - start_handle + 1 == svc_size); range[0] = start_handle; range[1] = start_handle + svc_size - 1; } static void register_vendor_service(struct temp_sensor_adapter *adapter, uint16_t range[2]) { uint16_t start_handle, h; const int svc_size = 3; uint8_t atval[256]; bt_uuid_t uuid; bt_uuid16_create(&uuid, VENDOR_SPECIFIC_SVC_UUID); start_handle = attrib_db_find_avail(adapter->adapter, &uuid, svc_size); if (start_handle == 0) { error("Not enough free handles to register service"); return; } DBG("start_handle=0x%04x", start_handle); h = start_handle; /* Secondary Service: Vendor Specific Service */ bt_uuid16_create(&uuid, GATT_SND_SVC_UUID); put_le16(VENDOR_SPECIFIC_SVC_UUID, &atval[0]); attrib_db_add(adapter->adapter, h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2); /* Vendor Specific Type characteristic definition */ bt_uuid16_create(&uuid, GATT_CHARAC_UUID); atval[0] = GATT_CHR_PROP_READ; put_le16(h + 1, &atval[1]); put_le16(VENDOR_SPECIFIC_TYPE_UUID, &atval[3]); attrib_db_add(adapter->adapter, h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5); /* Vendor Specific Type characteristic value */ bt_uuid16_create(&uuid, VENDOR_SPECIFIC_TYPE_UUID); atval[0] = 0x56; atval[1] = 0x65; atval[2] = 0x6E; atval[3] = 0x64; atval[4] = 0x6F; atval[5] = 0x72; attrib_db_add(adapter->adapter, h, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 6); g_assert(h - start_handle + 1 == svc_size); range[0] = start_handle; range[1] = start_handle + svc_size - 1; } static int temp_sensor_adapter_probe(struct btd_adapter *adapter) { uint16_t manuf1_range[2] = {0, 0}, manuf2_range[2] = {0, 0}; uint16_t vendor_range[2] = {0, 0}; struct temp_sensor_adapter *gadapter; gadapter = g_new0(struct temp_sensor_adapter, 1); gadapter->adapter = btd_adapter_ref(adapter); if (!register_temp_sensor_service(adapter)) { DBG("Temperature sensor service could not be registered"); temp_sensor_adapter_free(gadapter); return -EIO; } register_manuf1_service(gadapter, manuf1_range); register_vendor_service(gadapter, vendor_range); adapters = g_slist_append(adapters, gadapter); return 0; } static void temp_sensor_adapter_remove(struct btd_adapter *adapter) { struct temp_sensor_adapter *gadapter; GSList *l; l = g_slist_find_custom(adapters, adapter, adapter_cmp); if (l == NULL) return; gadapter = l->data; adapters = g_slist_remove(adapters, gadapter); temp_sensor_adapter_free(gadapter); } static struct btd_adapter_driver temp_sensor_adapter_driver = { .name = "temperature-sensor-adapter-driver", .probe = temp_sensor_adapter_probe, .remove = temp_sensor_adapter_remove, }; static int temp_sensor_init(void) { return btd_register_adapter_driver(&temp_sensor_adapter_driver); } static void temp_sensor_exit(void) { btd_unregister_adapter_driver(&temp_sensor_adapter_driver); } BLUETOOTH_PLUGIN_DEFINE(temp_sensor, VERSION, BLUETOOTH_PLUGIN_PRIORITY_LOW, temp_sensor_init, temp_sensor_exit) References:https://books.google.co.in/books/about/Inside_Bluetooth_Low_Energy.html?id=-LMq0NhoEQgC&redir_esc=yhttps://www.bluetooth.com/specifications/profiles-overviewhttps://en.wikipedia.org/wiki/List_of_Bluetooth_profiles

Aziro Marketing

blogImage

How to create a Smart Mirror Using Raspberry Pi

Smart MirrorThis blog shows how to enable Smart Mirror using Raspberry Pi. It is used to convert your home/ room/ office work space/ commercial space into your personal assistant with the help of smart mirror that shows up your latest calendar events, weather forecast etc. It can be used as notice board with the help of a mirror.Let’s dive into how to setup this up:1. Components Required for this ProjectRaspberry Pi (Currently used version 2)SD CardWi-Fi dongleMonitorTwo-way Acrylic MirrorFirstly, we need to setup basic installation for Raspberry Pi, you can refer to installation tutorials from https://www.raspberrypi.org/downloads/2. Setting up the Raspberry PIFormat the SD card with FAT32 as format and Copy the Noobs OS into thatConnect Raspberry with HMDI Output monitor (LED/LCD TV or any monitor that takes HDMI input).Connect with the power and wait till Raspberry pi OS setup is completed and restart it.3. Connecting with weatherCreate an account with https://darksky.net/dev and get the API Key to call the weather API to get the weather info (Weather_api_token).4. Real workhorsesmartmirror.py is the python script which does the actual work of showing the events belonging to the signed up user.5. Changes to the scriptReplace the token in smartmirror.py script as follows:Weather_api_token = ‘XXXXXXXXXXXXXXXXXXXXXXX’  #Replace with your token6. Connecting with Google CalendarRun the script “get_cal_events” available at /home/pi/Smartmirror the location.It will open the Browser and it prompts for Google account from which the calendar needs to be imported. Once the authentication is completed, the API key will be generated and stored locally. Please make sure you are connected to the internet while trying to execute this script. This script will update the events for every 20 minutes which can be modified.It will create Image with weather, calendar, clock and run it.7. Configuring Raspberry PiOpen file “sudo nano /boot/config.txt”Add the following code belowdisplay_rotate=1This will enable the rotation of the screen.If the rotation needs to be disabled just change the value to zero like below.display_rotate=0Then reboot raspberry Pi using the following command“sudo shutdown –r now”8. Future additionsThese functionalities can be added in the future.Face recognition.Touch screen for viewing maps.Video playback.Control electrical components like lights, fans and others using voice commands.

Aziro Marketing

blogImage

How to cross-compile Embedded Linux (Part 3): Buildroot

This is the continuation of series of blogs about cross compiling, loading bootloader, Linux kernel and filesystem into an embedded development platform. Please check the previous blog for the target hardware and setup that is needed.In short, the embedded development platform is beaglebone black with MicroSD card. We have already partitioned the card in the first blog and please look into it for more infoSo far we have compiled U-Boot, Linux kernel and then loaded the builded images into the target hardware which is beaglebone black. At the end of the Linux kernel bootup log we got an error like “No working init found”. What it actually means is that it is not able to find the init binary which can be executed. Init in *nix based machines is the parent of all the processes except the kernel threads.Basically to solve this issue we need a filesystem which provides us the init binary.BuildrootBuildroot is free and open-source software, maintained by Peter Korsgaard and licensed under version 2 or later of the GNU General Public License (GPL). It is a group of Makefiles and build script files which simplifies and automates the process of building a complete embedded Linux environment. For cross compiling to different target processor it can automatically build the required cross compilation toolchain. It has the support to create bootloader, Linux kernel and a root filesystem. It builds these independently also depending upon the user input.It is primarily intended to be used with small or embedded systems based on various computer architectures including x86, ARM, MIPS and PowerPC.Numerous architectures and it also supports their variants. It also comes with default configurations for several development platforms such as Raspberry Pi, Cubieboard, etc. It is used as the basis for many third party projects and by many product development teams as it makes the process simple. It is organized as automatically downloaded packages which contain the source code of various userspace applications, libraries and system utilities. Root file system images, which are the final results, may be built using various file systems, including cramfs, JFFS2, romfs, SquashFS and UBIFS.kasi@kasi-desktop:~/git$ git clone git://git.buildroot.net/buildrootConfigure the Buildrootkasi@kasi-desktop:~/git$ cd buildroot/The following command shows the list of files that is provided by buildroot.kasi@kasi-desktop:~/git/buildroot$ ls -l/Now execute the following command:kasi@kasi-desktop:~/git/buildroot$ make menuconfig/Figure 1. Initial menu when menuconfig is executed.We need to select “Target options” here.In the following image (figure 2), architecture is shown as i386 by default target.Figure 2. Target Architecture selectionWe need to change that to ARM little endian as in the following image:Figure 3. Target Architecture selection — ARM processor is selected.Next we need to move to the Target Architecture variant option. After choosing target architecture we can see that the Target Architecture variant is set to arm926t.Check the following image.Figure 4. Target Architecture variantBeagle bone black is actually based on Cortex-A8 variant and it is exactly what we need to choose.Figure 5. Target Architecture variant — Cortex-A8 is selected.After choosing these two parameters we need to save this config file and start the build. There are a lot of other options like choosing which C library to use and various packages selection options, for the moment let us save the config file as below.Figure 6. Save the config fileconfiguration written to /home/kasi/git/buildroot/.config*** End of the configuration.*** Execute ‘make’ to start the build or try ‘make help'[/vc_column_text]BuildAs with other blogs we now need to give ‘make’ command to start the compilation process.kasi@kasi-desktop:~/git/buildroot$ makeWe need to wait for 15 to 20 minutes depending upon the build machine hardware specs and network bandwidth available for the build to complete.Final StepsGenerating root filesystem image rootfs.tar rm -f /home/kasi/git/buildroot/output/build/_fakeroot.fs rm -f /home/kasi/git/buildroot/output/target/THIS_IS_NOT_YOUR_ROOT_FILESYSTEM rm -f /home/kasi/git/buildroot/output/build/_users_table.txt echo '#!/bin/sh' > /home/kasi/git/buildroot/output/build/_fakeroot.fs echo "set -e" >> /home/kasi/git/buildroot/output/build/_fakeroot.fs echo "chown -h -R 0:0 /home/kasi/git/buildroot/output/target" >> /home/kasi/git/buildroot/output/build/_fakeroot.fs printf '   \n' >> /home/kasi/git/buildroot/output/build/_users_table.txt PATH="/home/kasi/git/buildroot/output/host/bin:/home/kasi/git/buildroot/output/host/sbin:/home/kasi/git/buildroot/output/host/usr/bin:/home/kasi/git/buildroot/output/host/usr/sbin:/home/kasi/git/gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabihf/bin:/home/kasi/bin:/home/kasi/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin" /home/kasi/git/buildroot/support/scripts/mkusers /home/kasi/git/buildroot/output/build/_users_table.txt /home/kasi/git/buildroot/output/target >> /home/kasi/git/buildroot/output/build/_fakeroot.fs cat system/device_table.txt > /home/kasi/git/buildroot/output/build/_device_table.txt printf '   /bin/busybox                     f 4755 0  0 - - - - -\n /dev/console c 622 0 0 5 1 - - -\n\n' >> /home/kasi/git/buildroot/output/build/_device_table.txt echo "/home/kasi/git/buildroot/output/host/usr/bin/makedevs -d /home/kasi/git/buildroot/output/build/_device_table.txt /home/kasi/git/buildroot/output/target" >> /home/kasi/git/buildroot/output/build/_fakeroot.fs printf '   tar  -cf /home/kasi/git/buildroot/output/images/rootfs.tar --numeric-owner -C /home/kasi/git/buildroot/output/target .\n' >> /home/kasi/git/buildroot/output/build/_fakeroot.fs chmod a+x /home/kasi/git/buildroot/output/build/_fakeroot.fs PATH="/home/kasi/git/buildroot/output/host/bin:/home/kasi/git/buildroot/output/host/sbin:/home/kasi/git/buildroot/output/host/usr/bin:/home/kasi/git/buildroot/output/host/usr/sbin:/home/kasi/git/gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabihf/bin:/home/kasi/bin:/home/kasi/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin" /home/kasi/git/buildroot/output/host/usr/bin/pseudo-wrapper -- /home/kasi/git/buildroot/output/build/_fakeroot.fs rootdir=/home/kasi/git/buildroot/output/target table='/home/kasi/git/buildroot/output/build/_device_table.txt' /usr/bin/install -m 0644 support/misc/target-dir-warning.txt /home/kasi/git/buildroot/output/target/THIS_IS_NOT_YOUR_ROOT_FILESYSTEM kasi@kasi-desktop:~/git/buildroot$The build is completed and the zipped file system is available in the following location:kasi@kasi-desktop:~/git/buildroot$ ls output/images/ rootfs.tar kasi@kasi-desktop:~/git/buildroot$We need to untar this file and copy the contents into the Micro SD card’s fs partition (ext4 partition with size more than 4GB).kasi@kasi-desktop:~/git/buildroot$ cd output/images/ kasi@kasi-desktop:~/git/buildroot/output/images$ ls rootfs.tar kasi@kasi-desktop:~/git/buildroot/output/images$ mount /dev/sdc2 on /media/kasi/fs type ext4 (rw,nosuid,nodev,relatime,data=ordered,uhelper=udisks2) /dev/sdc1 on /media/kasi/BOOT type vfat (rw,nosuid,nodev,relatime,uid=1000,gid=1000,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,showexec,utf8,flush,errors=remount-ro,uhelper=udisks2) kasi@kasi-desktop:~/git/buildroot/output/images$It is a better idea to copy the zip file into the Micro SD card’s fs partition and unzip it there.kasi@kasi-desktop:~/git/buildroot/output/images$ sudo cp rootfs.tar /media/kasi/fs/ [sudo] password for kasi: kasi@kasi-desktop:~/git/buildroot/output/images$ sync kasi@kasi-desktop:~/git/buildroot/output/images$ cd /media/kasi/fs kasi@kasi-desktop:/media/kasi/fs$ ls lost+found  rootfs.tar kasi@kasi-desktop:/media/kasi/fs$ sudo tar xf rootfs.tar kasi@kasi-desktop:/media/kasi/fs$ ls -l total 1488 drwxr-xr-x 2 root root 4096 Nov 18 16:48 bin drwxr-xr-x 4 root root 4096 Nov 18 16:48 dev drwxr-xr-x 5 root root 4096 Nov 18 16:48 etc drwxr-xr-x 2 root root 4096 Nov 18 16:48 lib lrwxrwxrwx 1 root root   3 Nov 18 16:38 lib32 -> lib lrwxrwxrwx 1 root root   11 Nov 18 16:47 linuxrc -> bin/busybox drwx------ 2 root root   16384 Nov  5 18:53 lost+found drwxr-xr-x 2 root root 4096 Nov 18 16:22 media drwxr-xr-x 2 root root 4096 Nov 18 16:22 mnt drwxr-xr-x 2 root root 4096 Nov 18 16:22 opt drwxr-xr-x 2 root root 4096 Nov 18 16:22 proc drwx------ 2 root root 4096 Nov 18 16:22 root -rw-r--r-- 1 root root 1443840 Nov 22 11:39 rootfs.tar drwxr-xr-x 2 root root 4096 Nov 18 16:22 run drwxr-xr-x 2 root root 4096 Nov 18 16:48 sbin drwxr-xr-x 2 root root 4096 Nov 18 16:22 sys drwxrwxrwt 2 root root 4096 Nov 18 16:22 tmp drwxr-xr-x 6 root root 4096 Nov 18 16:47 usr drwxr-xr-x 4 root root 4096 Nov 18 16:48 var kasi@kasi-desktop:/media/kasi/fs$The Micro SD card now contains all the needed images/binaries to boot up a complete embedded Linux machine. Remove the Micro SD card from the build machine and by following the boot procedure to boot using Micro SD card we should now be able to get the shell prompt.Sample Log from TargetU-Boot SPL 2016.11-rc3-00044-g38cacda-dirty (Nov 14 2016 - 13:02:35) ############################ ##### AZIRO Technologies #### #####   We were here #### ############################ Trying to boot from MMC1 reading uboot.env ** Unable to read "uboot.env" from mmc0:1 ** Using default environment reading u-boot.img reading u-boot.img reading u-boot.img reading u-boot.img U-Boot 2016.11-rc3-00044-g38cacda-dirty (Nov 14 2016 - 13:02:35 +0530) CPU  : AM335X-GP rev 2.0 Model: TI AM335x BeagleBone Black DRAM:  512 MiB NAND:  0 MiB MMC:   OMAP SD/MMC: 0, OMAP SD/MMC: 1 reading uboot.env ** Unable to read "uboot.env" from mmc0:1 ** Using default environment not set. Validating first E-fuse MAC Net:   Could not get PHY for ethernet@4a100000: addr 0 eth0: ethernet@4a100000 Hit any key to stop autoboot:  0 switch to partitions #0, OK mmc0 is current device SD/MMC found on device 0 reading boot.scr ** Unable to read file boot.scr ** reading uEnv.txt 193 bytes read in 3 ms (62.5 KiB/s) Loaded env from uEnv.txt Importing environment from mmc0 ... Running uenvcmd ... reading uImage 3852896 bytes read in 251 ms (14.6 MiB/s) reading am335x-boneblack.dtb 34185 bytes read in 8 ms (4.1 MiB/s) ## Booting kernel from Legacy Image at 80008000 ...   Image Name:   Linux-4.8.7   Created:   2016-11-15   9:57:37 UTC   Image Type:   ARM Linux Kernel Image (uncompressed)   Data Size: 3852832 Bytes = 3.7 MiB   Load Address: 80008000   Entry Point:  80008000   Verifying Checksum ... OK ## Flattened Device Tree blob at 88008000   Booting using the fdt blob at 0x88008000   Loading Kernel Image ... OK   Loading Device Tree to 8fff4000, end 8ffff588 ... OK Starting kernel ... [ 0.000000] Booting Linux on physical CPU 0x0 [ 0.000000] ################################## [ 0.000000] ######   AZIRO Technologies  ###### [ 0.000000] ######   We were here too   ###### [ 0.000000] ################################## [ 0.000000] Linux version 4.8.7 (kasi@kasi-desktop) (gcc version 6.1.1 20160711 (Linaro GCC 6.1-2016.08) ) #3 SMP Tue Nov 15 15:27:26 IST 2016 [ 0.000000] CPU: ARMv7 Processor [413fc082] revision 2 (ARMv7), cr=10c5387d [ 1.850061] EXT4-fs (mmcblk0p2): couldn't mount as ext3 due to feature incompatibilities [ 1.873734] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null) [ 1.882582] VFS: Mounted root (ext4 filesystem) readonly on device 179:2. [ 1.892735] devtmpfs: mounted [ 1.898228] Freeing unused kernel memory: 1024K (c0b00000 - c0c00000) [ 2.005862] EXT4-fs (mmcblk0p2): warning: mounting fs with errors, running e2fsck is recommended [ 2.018977] EXT4-fs (mmcblk0p2): re-mounted. Opts: data=ordered Starting logging: OK Initializing random number generator... done. Starting network: OK             ##### AZIRO Technologies -- Welcome to Buildroot #####                   ##### We are everywhere ##### buildroot login: root # uname -a Linux buildroot 4.8.7 #3 SMP Tue Nov 15 15:27:26 IST 2016 armv7l GNU/LinuxWe are able reach the shell prompt with the file system we have created.Hope this series of blogs helps you to bring up an embedded device based on Linux.

Aziro Marketing

blogImage

How to setup a bootloader for an embedded linux machine

This is a three part series of blogs which explains the complete procedure to cross compileBootloaderKernel/O.SFile systemThis will be done for ARM processor based development platform.In short, this blog series explains how to setup an embedded linux machine that suits your needsDevelopment environment prerequisitesLinux machine running any flavour of ubuntu, fedora or arch linux.Internet connection.Hardware needed1.ARM based development board.a.This is very important as the build process and the cross compiler we choose depends on the type of processor. For this blog series we are using beaglebone black development which is based on ARMv7 architecture.2.4/8 GB Micro SD Card.3.USB to Serial adaptor.Topics discussed in this documentWhat is Bootloader?Das U-Boot — the Universal Boot LoaderStages in boot loadingDownloading the sourceBrief about the directories and the functionality it providesCross compiling bootloader for ARM based target platformSetup the environment variablesStart the buildMicro SD card Booting procedure in beaglebone blackWhat is Bootloader?There are so many answers to this question, but if you look at the core of all the answers it would contain some kind of initialization. In short this is the piece of software which is executed as soon as you turn on your hardware device. The hardware device can be anything, from your mobile phones, routers, microwave ovens, smart tv, and to the world’s fastest supercomputer. After all, everything has a beginning right?The reason I said there are so many ways to answer this question, is because the use case of each device is different, and we need to choose the bootloader carefully, which initializes the device. So much research and decision making time is spent on this to make sure that the devices which are initialized are absolutely needed. Everyone likes their devices to boot up fast.In embedded systems the bootloader is a special piece of software whose main purpose is to load the kernel and hand over the control to it. To achieve this, it needs to initialize the required peripherals which helps the device to carry out its intended functionality. In other words, it initializes the absolutely needed peripherals alone and hands over the control to the O.S aka kernel.Das U-Boot — the Universal Boot LoaderU-Boot is the most popular boot loader in linux based embedded devices. It is released as open source under the GNU GPLv2 license. It supports a wide range of microprocessors like MIPS, ARM, PPC, Blackfin, AVR32 and x86. It even supports FPGA based nios platforms. If your hardware design is based out of any of these processors and if you are looking for a bootloader the best bet is to try U-Boot first. It also supports different methods of booting which is pretty much needed on fallback situations.For example, it has support to boot from USB, SD Card, NOR and NAND flash (non volatile memory). It also has the support to boot linux kernel from the network using TFTP. The list of filesystems supported by U-Boot is huge. So you are covered in all aspects that is needed from a bootloader and more so.Last but not least, it has a command line interface which gives you a very easy access to it and try many different things before finalizing your design. You configure U-Boot for various boot methods like MMC, USB, NFS or NAND based and it allows you to test the physical RAM of any issues.Now its upto the designer to pick what device he wants and then use U-Boot to his advantage.Stages in boot loadingFor starters, U-Boot is both a first stage and second stage bootloader. When U-Boot is compiled we get two images, first stage (MLO) and second stage (u-boot.img) images. It is loaded by the system’s ROM code (this code resides inside the SoC’s and it is already preprogrammed) from a supported boot device. The ROM code checks for the various bootable devices that is available. And starts execution from the device which is capable of booting. This can be controlled through jumpers, though some resistor based methods also exists. Since each platform is different and it is advised to look into the platforms datasheet for more details.Stage 1 bootloader is sometimes called a small SPL (Secondary Program Loader). SPL would do initial hardware configuration and load the rest of U-Boot i.e. second stage loader. Regardless of whether the SPL is used, U-Boot performs both first-stage and second-stage booting.In first stage, U-Boot initializes the memory controller and SDRAM. This is needed as rest of the execution of the code depends on this. Depending upon the list of devices supported by the platform it initializes the rest. For example, if your platform has the capability to boot through USB and there is no support for network connectivity, then U-Boot can be programmed to do exactly the same.If you are planning to use linux kernel, then setting up of the memory controller is the only mandatory thing expected by linux kernel. If memory controller is not initialized properly then linux kernel won’t be able to boot.Block Diagram of the targetThe above is the block diagram of AM335X SoC.Downloading the sourceU-Boot source code is maintained using git revision control. Using git we can clone the latest source code from the repo.kasi@kasi-desktop:~/git$ git clone git://git.denx.de/u-boot.gitBrief about the directories and the functionality it providesarch –> Contains architecture specific code. This is the piece of code which initializes the CPU and board specific peripheral devices.board → Source in both arch and board directory work in tandem to initialize the memory and other devices.cmd –> Contains code which adds command line support to carry out different activity depending on the developer’s requirement. For example, command line utilities are provided to erase NAND flash and reprogram it. We will be using similar commands in the next blog.configs –> Contains the platform level configuration details. This is very much platform specific. The configs are much like a static mapping with reference to the platform’s datasheet.drivers –> This directory needs a special mention as it has support for a lot of devices:Each subdirectory under the driver directory corresponds to a particular device type. This structure is followed in accordance with the linux kernel. For example, network drivers are all accumulated inside the net directory:kasi@kasi-desktop:~/git/u-boot$ ls drivers/net/ -l total 2448 -rw-rw-r-- 1 kasi kasi 62315 Nov 11 15:05 4xx_enet.c -rw-rw-r-- 1 kasi kasi 6026 Nov 11 15:05 8390.hThis makes sure the code is not bloated and it is much easier for us to navigate and make the needed changes.fs –> Contains the code which adds support for filesystems. As mentioned earlier, U-Boot has a rich filesystem support. It supports both read only file system like cramfs and also journalling file system like jffs2 which is used on NAND flash based devices.include –> This is a very important directory in U-Boot. It not only contains the header files but also the files which define platform specific information like supported baud rates, starting RAM address, stack size, default command line arguments etc.lib –> Contains support for library files. They provide the needed helper functions used by U-Boot.net –> Contains support for networking protocols like ARP, TFTP, Ping, Bootp and etc.scripts and tools –> Contains helper scripts to create images and binaries. It contains scripts to create a patch file (hopefully with some useful fixes) in the correct format if we are planning to send it the development community.With the source code available and some understanding about the directory structure let us do what we actually want to do i.e. create a bootloaderSince the target board which we are using is based on ARM processor we will need a cross compiler which helps us to create binaries to run on that processor. There are a lot of options for this. Linaro provides the latest cross tool for ARM based processors and it is very easy to get. For this reason, we have chosen to go for the cross tool provided by linaro.Cross compiling bootloader for ARM based target platformFor cross compiling we can need to download the toolchain from the linaro website using the below link:kasi@kasi-desktop:~/git$ wget https://releases.linaro.org/components/toolchain/binaries/latest/arm-linux-gnueabihf/gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabihf.tar.xzThe toolchain comes compressed as tar file and we can unzip it using the below command:kasi@kasi-desktop:~/git$ tar xf gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabihf.tar.xzSetup the environment variablesWith the pre build tool chain, we need to set up a few environment variables like path of the toolchain before proceeding to compile U-Boot. Below are the shell commands that we need to issue.export PATH=/gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabihf/bin:$PATH; export CROSS_COMPILE=arm-linux-gnueabihf- export ARCH=arm;In our work space points to /home/kasi/git/ as this is the workspace which we are using.The exact command from our machine is:kasi@kasi-desktop:~/git/u-boot$ export PATH=/home/kasi/git/gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabihf/bin:$PATH kasi@kasi-desktop:~/git/u-boot$ export CROSS_COMPILE=arm-linux-gnueabihf- kasi@kasi-desktop:~/git/u-boot$ export ARCH=arm;Please double check the above commands so that it suits your workspace.Config FileWith everything setup it’s time to choose the proper config file and start the compilation.The board which we are using is beagle bone black which is based on TI’s AM3358 SoC.So we need to look for similar kind of name in include/configs. The file which corresponds to this board is “am335x_evm.h”So from command line we need to execute the below command:kasi@kasi-desktop:~/git/u-boot$ make am335x_evm_defconfig  HOSTCC  scripts/basic/fixdep  HOSTCC  scripts/kconfig/conf.o  SHIPPED scripts/kconfig/zconf.tab.c  SHIPPED scripts/kconfig/zconf.lex.c  SHIPPED scripts/kconfig/zconf.hash.c  HOSTCC  scripts/kconfig/zconf.tab.o  HOSTLD  scripts/kconfig/conf # # configuration written to .config # kasi@kasi-desktop:~/git/u-boot$There are a lot of things that happened in the background when the above command was executed. We don’t want to go much deeper into that as that could be another blog altogether…!We have created the config file which is used by U-Boot in the build process. For those who want to know more, please open the “.config” file and check it. Modifications can be done here to the config file directly but we shall discuss about this later.Start the buildTo start the build we need to give the most used/abused command in the embedded linux programmer’s life which is make.kasi@kasi-desktop:~/git/u-boot$ make scripts/kconfig/conf  --silentoldconfig Kconfig  CHK  include/config.h  UPD  include/config.h  CC   examples/standalone/hello_world.o  LD   examples/standalone/hello_world  OBJCOPY examples/standalone/hello_world.srec  OBJCOPY examples/standalone/hello_world.bin  LDS  u-boot.lds  LD  u-boot  OBJCOPY u-boot-nodtb.bin ./scripts/dtc-version.sh: line 17: dtc: command not found ./scripts/dtc-version.sh: line 18: dtc: command not found *** Your dtc is too old, please upgrade to dtc 1.4 or newer Makefile:1383: recipe for target 'checkdtc' failed make: *** [checkdtc] Error 1 kasi@kasi-desktop:~/git/u-boot$If you are compiling U-Boot for the first time, then there are chances that you may get the above error. Since the build machine which we are using didn’t have the device-tree-compiler package installed we got the above error.Dependency installation (if any)kasi@kasi-desktop:~/git/u-boot$ sudo apt-cache search dtc [sudo] password for kasi: device-tree-compiler - Device Tree Compiler for Flat Device Trees kasi@kasi-desktop:~/git/u-boot$ sudo apt install device-tree-compiler Again makekasi@kasi-desktop:~/git/u-boot$ make  CHK include/config/uboot.release  CHK include/generated/version_autogenerated.hSimple ls -l will show the first stage bootloader and second stage bootloader.kasi@kasi-desktop:~/git/u-boot$ ls -l total 9192 drwxrwxr-x   2 kasi kasi   4096 Nov 11 15:05 api drwxrwxr-x  18 kasi kasi   4096 Nov 11 15:05 arch drwxrwxr-x 220 kasi kasi   4096 Nov 11 15:05 board drwxrwxr-x   3 kasi kasi   12288 Nov 14 13:02 cmd drwxrwxr-x   5 kasi kasi   12288 Nov 14 13:02 common -rw-rw-r--   1 kasi kasi   2260 Nov 11 15:05 config.mk drwxrwxr-x   2 kasi kasi   65536 Nov 11 15:05 configs drwxrwxr-x   2 kasi kasi   4096 Nov 14 13:02 disk drwxrwxr-x   8 kasi kasi   12288 Nov 11 15:05 doc drwxrwxr-x  51 kasi kasi   4096 Nov 14 13:02 drivers drwxrwxr-x   2 kasi kasi   4096 Nov 14 13:03 dts drwxrwxr-x   4 kasi kasi   4096 Nov 11 15:05 examples drwxrwxr-x  12 kasi kasi   4096 Nov 14 13:03 fs drwxrwxr-x  29 kasi kasi   12288 Nov 11 18:48 include -rw-rw-r--   1 kasi kasi   1863 Nov 11 15:05 Kbuild -rw-rw-r--   1 kasi kasi   12416 Nov 11 15:05 Kconfig drwxrwxr-x  12 kasi kasi   4096 Nov 14 13:03 lib drwxrwxr-x   2 kasi kasi   4096 Nov 11 15:05 Licenses -rw-rw-r--   1 kasi kasi   11799 Nov 11 15:05 MAINTAINERS -rw-rw-r--   1 kasi kasi   54040 Nov 11 15:05 Makefile -rw-rw-r--   1 kasi kasi   79808 Nov 14 13:03 MLO -rw-rw-r--   1 kasi kasi   79808 Nov 14 13:03 MLO.byteswap drwxrwxr-x   2 kasi kasi   4096 Nov 14 13:03 net drwxrwxr-x   6 kasi kasi   4096 Nov 11 15:05 post -rw-rw-r--   1 kasi kasi  223974 Nov 11 15:05 README drwxrwxr-x   5 kasi kasi   4096 Nov 11 15:05 scripts -rw-rw-r--   1 kasi kasi  17 Nov 11 15:05 snapshot.commit drwxrwxr-x  12 kasi kasi   4096 Nov 14 13:03 spl -rw-rw-r--   1 kasi kasi   75282 Nov 14 13:03 System.map drwxrwxr-x  10 kasi kasi   4096 Nov 14 13:03 test drwxrwxr-x  15 kasi kasi   4096 Nov 14 13:02 tools -rwxrwxr-x   1 kasi kasi 3989228 Nov 14 13:03 u-boot -rw-rw-r--   1 kasi kasi  466702 Nov 14 13:03 u-boot.bin -rw-rw-r--   1 kasi kasi   0 Nov 14 13:03 u-boot.cfg.configs -rw-rw-r--   1 kasi kasi   36854 Nov 14 13:03 u-boot.dtb -rw-rw-r--   1 kasi kasi  466702 Nov 14 13:03 u-boot-dtb.bin -rw-rw-r--   1 kasi kasi  628808 Nov 14 13:03 u-boot-dtb.img -rw-rw-r--   1 kasi kasi  628808 Nov 14 13:03 u-boot.img -rw-rw-r--   1 kasi kasi   1676 Nov 14 13:03 u-boot.lds -rw-rw-r--   1 kasi kasi  629983 Nov 14 13:03 u-boot.map -rwxrwxr-x   1 kasi kasi  429848 Nov 14 13:03 u-boot-nodtb.bin -rwxrwxr-x   1 kasi kasi 1289666 Nov 14 13:03 u-boot.srec -rw-rw-r--   1 kasi kasi  147767 Nov 14 13:03 u-boot.sym kasi@kasi-desktop:~/git/u-boot$MLO is the first stage bootloader and u-boot.img is the second stage bootloader.With the bootloader available it’s time to partition the Micro SD card, load these images and test it on the target.PartitionWe are using an 8GB Micro SD card and using “gparted” (gui based partition tool) to partition it. It is a much easier approach to use gparted and create the filesystems. We have created two partitions:1. FAT16 of size 80MB with boot flag enabled.2. EXT4 of size more than 4GB.Choosing the size of the partition is an availability as well as a personal choice. One important thing to note here is that the FAT16 partition has the boot flag set. This is needed for us to boot the device using the Micro SD card. Please see the image below to get a clear picture of the partitions in the Micro SD card.After the creating the partitions in the Micro SD card, remove the card from the build machine and insert it again. In most of the modern distro’s partitions in the Micro SD card get auto mounted which will confirm us that the partitions are created correctly. It will help us to cross verify the created partitions.Copy the imagesNow it’s time to copy the builded images into the Micro SD card. When the Micro SD card is inserted into the build machine it was automatically mounted in /media/kasi/BOOT directory.kasi@kasi-desktop:~/git/u-boot$ mount /dev/sdc2 on /media/kasi/fs type ext4 (rw,nosuid,nodev,relatime,data=ordered,uhelper=udisks2) /dev/sdc1 on /media/kasi/BOOT type vfat (rw,nosuid,nodev,relatime,uid=1000,gid=1000,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,showexec,utf8,flush,errors=remount-ro,uhelper=udisks2) We need to copy just the MLO and u-boot.img file into the BOOT partition of the micro SD card. kasi@kasi-desktop:~/git/u-boot$ cp MLO /media/kasi/BOOT/ kasi@kasi-desktop:~/git/u-boot$ cp u-boot.img /media/kasi/BOOT/ kasi@kasi-desktop:~/git/u-boot$With the above commands we have loaded the first stage bootloader as well as the second stage bootloader into the bootable Micro SD card.Micro SD card Booting procedure in beaglebone blackSince the target board has both eMMC and MicroSD card slot, on power up it tries to boot from both the places. To make sure it boots from MicroSD card we need to keep the button near the MicroSD card slot pressed while providing power to the device. This makes sure that the board sees the MicroSD card first and loads the first stage and second stage bootloader which we just copied there.Above flowchart shows the booting procedure of the target.Serial HeaderThe above diagram shows the close up of the serial port header details of that target. You should connect your pinouts from USB to TTL Serial Cable (if you are using one) to these pins in the target to see the below log.Below is the output from the serial port while loading U-Boot which was compiled by us.U-Boot SPL 2016.11-rc3-00044-g38cacda-dirty (Nov 14 2016 - 13:02:35) ############################ ##### AZIRO Technologies #### #####   We were here #### ############################ Trying to boot from MMC1 reading uboot.env ** Unable to read "uboot.env" from mmc0:1 ** Using default environment reading u-boot.img reading u-boot.img reading u-boot.img reading u-boot.img U-Boot 2016.11-rc3-00044-g38cacda-dirty (Nov 14 2016 - 13:02:35 +0530) CPU  : AM335X-GP rev 2.0 Model: TI AM335x BeagleBone Black DRAM:  512 MiB NAND:  0 MiB MMC:   OMAP SD/MMC: 0, OMAP SD/MMC: 1 reading uboot.env ** Unable to read "uboot.env" from mmc0:1 ** Using default environment not set. Validating first E-fuse MAC Net:   eth0: ethernet@4a100000 Hit any key to stop autoboot:  0 => =>As you can clearly see this is the U-Boot which we compiled and loaded into the target (Check for string AZIRO technologies in the log, second line of the output.First stage bootloader checks and loads the u-boot.img into RAM and hands over the control to it which is the second stage bootloader. As shared before U-Boot also provides us with a cli which can be used to set up various parameters like IP address, load addresses and a lot more which the developer can use for tweaking and testing purposes.To the second stage bootloader we need to provide proper kernel image to load and proceed with the next step of bootstrapping. We shall discuss about this in next blog..filledCheckboxes input[type="checkbox"]{opacity:0;display :none;}.multiStepFormBody button.close{z-index:99;}

Aziro Marketing

EXPLORE ALL TAGS
2019 dockercon
Advanced analytics
Agentic AI
agile
AI
AI ML
AIOps
Amazon Aws
Amazon EC2
Analytics
Analytics tools
AndroidThings
Anomaly Detection
Anomaly monitor
Ansible Test Automation
apache
apache8
Apache Spark RDD
app containerization
application containerization
applications
Application Security
application testing
artificial intelligence
asynchronous replication
automate
automation
automation testing
Autonomous Storage
AWS Lambda
Aziro
Aziro Technologies
big data
Big Data Analytics
big data pipeline
Big Data QA
Big Data Tester
Big Data Testing
bitcoin
blockchain
blog
bluetooth
buildroot
business intelligence
busybox
chef
ci/cd
CI/CD security
cloud
Cloud Analytics
cloud computing
Cloud Cost Optimization
cloud devops
Cloud Infrastructure
Cloud Interoperability
Cloud Native Solution
Cloud Security
cloudstack
cloud storage
Cloud Storage Data
Cloud Storage Security
Codeless Automation
Cognitive analytics
Configuration Management
connected homes
container
Containers
container world 2019
container world conference
continuous-delivery
continuous deployment
continuous integration
Coronavirus
Covid-19
cryptocurrency
cyber security
data-analytics
data backup and recovery
datacenter
data protection
data replication
data-security
data-storage
deep learning
demo
Descriptive analytics
Descriptive analytics tools
development
devops
devops agile
devops automation
DEVOPS CERTIFICATION
devops monitoring
DevOps QA
DevOps Security
DevOps testing
DevSecOps
Digital Transformation
disaster recovery
DMA
docker
dockercon
dockercon 2019
dockercon 2019 san francisco
dockercon usa 2019
docker swarm
DRaaS
edge computing
Embedded AI
embedded-systems
end-to-end-test-automation
FaaS
finance
fintech
FIrebase
flash memory
flash memory summit
FMS2017
GDPR faqs
Glass-Box AI
golang
GraphQL
graphql vs rest
gui testing
habitat
hadoop
hardware-providers
healthcare
Heartfullness
High Performance Computing
Holistic Life
HPC
Hybrid-Cloud
hyper-converged
hyper-v
IaaS
IaaS Security
icinga
icinga for monitoring
Image Recognition 2024
infographic
InSpec
internet-of-things
investing
iot
iot application
iot testing
java 8 streams
javascript
jenkins
KubeCon
kubernetes
kubernetesday
kubernetesday bangalore
libstorage
linux
litecoin
log analytics
Log mining
Low-Code
Low-Code No-Code Platforms
Loyalty
machine-learning
Meditation
Microservices
migration
Mindfulness
ML
mobile-application-testing
mobile-automation-testing
monitoring tools
Mutli-Cloud
network
network file storage
new features
NFS
NVMe
NVMEof
NVMes
Online Education
opensource
openstack
opscode-2
OSS
others
Paas
PDLC
Positivty
predictive analytics
Predictive analytics tools
prescriptive analysis
private-cloud
product sustenance
programming language
public cloud
qa
qa automation
quality-assurance
Rapid Application Development
raspberry pi
RDMA
real time analytics
realtime analytics platforms
Real-time data analytics
Recovery
Recovery as a service
recovery as service
rsa
rsa 2019
rsa 2019 san francisco
rsac 2018
rsa conference
rsa conference 2019
rsa usa 2019
SaaS Security
san francisco
SDC India 2019
SDDC
security
Security Monitoring
Selenium Test Automation
selenium testng
serverless
Serverless Computing
Site Reliability Engineering
smart homes
smart mirror
SNIA
snia india 2019
SNIA SDC 2019
SNIA SDC INDIA
SNIA SDC USA
software
software defined storage
software-testing
software testing trends
software testing trends 2019
SRE
STaaS
storage
storage events
storage replication
Storage Trends 2018
storage virtualization
support
Synchronous Replication
technology
tech support
test-automation
Testing
testing automation tools
thought leadership articles
trends
tutorials
ui automation testing
ui testing
ui testing automation
vCenter Operations Manager
vCOPS
virtualization
VMware
vmworld
VMworld 2019
vmworld 2019 san francisco
VMworld 2019 US
vROM
Web Automation Testing
web test automation
WFH

LET'S ENGINEER

Your Next Product Breakthrough

Book a Free 30-minute Meeting with our technology experts.

Aziro has been a true engineering partner in our digital transformation journey. Their AI-native approach and deep technical expertise helped us modernize our infrastructure and accelerate product delivery without compromising quality. The collaboration has been seamless, efficient, and outcome-driven.

Customer Placeholder
CTO

Fortune 500 company