Tuesday, December 30, 2014

Customizing a Linux distribution for an ARM Cortex-A9 SBC

The Yocto 1.7.1 (Dizzy branch) from Freescale source will be used for building a BSP for the i.MX 6 RIoTboard. The final image will consist of the following components

  • U-Boot version 2014.10 from the Freescale git repositories.
  • Linux kernel version 3.17.4 from the Freescale git repositories.
  • ext3 root filesystem with selected packages
The image will be built from the custom distribution (bsecdist) and custom image (bsec-image) defined in the last post. bsec-image is derived from core-image-minimal. The configuration changes below will add support for package tests to the baec-image. In addition, the profiling tools and static development libraries and header files will be added to the image. Finally, several standard userspace packages will be added to baec-image; namely, bison, flex, and and gunning. Last, several configuration directives will be added to the local configuration file so that source code archives, package versions, and accompanying license files are stored and cached in a local directory for future builds and compliance purposes.


1. Add profiling tools and static development packages to image

First, add the following profiling tools contained within the tools-profile package to the final image. Add static versions of the development packages to the target image. Therefore, add the IMAGE_FEATURES line to bsec-image.bb as follows.

sources/meta-bsec/recipes-bsec/images/bsec-image.bb should contain the following
SUMMARY = "A small image just capable of allowing a device to boot."
IMAGE_INSTALL = "packagegroup-core-boot ${ROOTFS_PKGMANAGE_BOOTSTRAP} ${CORE_IMAGE_EXTRA_INSTALL}"
IMAGE_LINGUAS = " "
LICENSE = "MIT"
inherit core-image
IMAGE_FEATURES += " tools-profile staticdev-pkgs"
IMAGE_ROOTFS_SIZE ?= "8192"


2. Add bison, flex, and gnupg packages to image

Now add bison, flex, and gnupg to the list of packages installed to the target image.
Add the following line to bsec-image.bb after the IMAGE_FEATURES line as follows.

sources/meta-bsec/recipes-bsec/images/bsec-image.bb should contain the following
SUMMARY = "A small image just capable of allowing a device to boot."
IMAGE_INSTALL = "packagegroup-core-boot ${ROOTFS_PKGMANAGE_BOOTSTRAP} ${CORE_IMAGE_EXTRA_INSTALL}"
IMAGE_LINGUAS = " "
LICENSE = "MIT"
inherit core-image
IMAGE_FEATURES += " tools-profile staticdev-pkgs"
CORE_IMAGE_EXTRA_INSTALL += "bison flex gnupg"
IMAGE_ROOTFS_SIZE ?= "8192"


3. List available packages

The full list of available packages can be viewed by executing the following command

$ bitbake -s

4. Setup source code archiving for all packages contained within image

Next, archive the source code for all packages contained within the image.
This can be achieved by adding the following two lines to the end of the build/conf/local.conf file

INHERIT += "archiver"
ARCHIVER_MODE[src] = "original"


5. Ensure license files are archived and included with binaries.

Subsequently, ensure that the license files accompany each binary in the final image by adding the following two lines to the end of the build/conf/local.conf file.

COPY_LIC_MANIFEST = "1"
COPY_LIC_DIRS = "1"

6. Add package testing to build

Now, add package testing to the build by adding the following two lines to bsec-image.bb

The contents of sources/meta-bsec/recipes-bsec/images/bsec-image.bb should be as follows
SUMMARY = "A small image just capable of allowing a device to boot."
IMAGE_INSTALL = "packagegroup-core-boot ${ROOTFS_PKGMANAGE_BOOTSTRAP} ${CORE_IMAGE_EXTRA_INSTALL}"
IMAGE_LINGUAS = " "
LICENSE = "MIT"
inherit core-image
IMAGE_FEATURES += " tools-profile staticdev-pkgs"
CORE_IMAGE_EXTRA_INSTALL += "bison flex gnupg"
DISTRO_FEATURES_append = " ptest"
EXTRA_IMAGE_FEATURES += "ptest-pkgs"

IMAGE_ROOTFS_SIZE ?= "8192"


7. Setup source code mirror so that package sources can be fetched from cache

Next, make sure that bitbake checks for all of the source tarballs in a local directory before going to the Internet to fetch them. This can be achieved by adding the following lines to the end of the build/conf/local.conf file.

SOURCE_MIRROR_URL ?= "file://${BSPDIR}/source-mirror/"
INHERIT += "own-mirrors"


8. Create shareable cache of git and svn backends

Finally, create a shareable cache of source code management backends by adding the following to the end of the build/conf/local.conf file.

BB_GENERATE_MIRROR_TARBALLS = “1”

After an initial build is performed, the directory contents of download/ can be recursively copied into source-mirror/ and the following line can be added to the end of the build/conf/local.conf file.

BB_NO_NETWORK = “1”

Consequently, all future builds will not fetch anything from the Internet and all package sources will be obtained from the sources in source-mirror.

9. Kick off the build

Kick off the build as follows

$ cd $HOME/src/fsl-community-bsp
$ MACHINE=imx6dl-riotboard . ./setup-environment build
$ bitbake bsec-image


10. Copy sources to mirror

Copy the sources from the downloads directory to source-mirror by executing the following commands

$ cd ..
$ cp -R downloads/*.* source-mirror/


After the build is complete, the license file for each package will be contained within the appropriately named subdirectory of build/tmp/deploy/licenses

The image manifest file build/tmp/deploy/images/imx6dl-riotboard/bsec-image-imx6dl-riotboard.manifest will contain a list of package names and associated versions for each of the packages in the image.


11. Boot the custom distribution image

After the build is complete, write the image to an SD Card as follows

$ cd build/tmp/deploy/images/imx6dl-riotboard
$ sudo umount /dev/sdX
$ sudo dd if=bsec-image-imx6dl-riotboard.sdcard of=/dev/sdb bs=1M
$ sudo sync


Insert the SD Card in the J6 SD Card slot on the bottom of the RiOTboard, connect the board to the Host over Serial UART, run minicom at 115200,8N1 from a terminal on the Host, and power on the board.

Monday, December 29, 2014

Creating a custom Linux distribution for an ARM Cortex-A9 SBC

The Yocto project provides an ideal platform for building a custom Linux distribution.  It's design was intended to model a machine.  The Yocto project or machine should take a number of inputs and produce an output.  The inputs to the machine are the specifications for the Linux distribution.  The output of the machine is the Linux distribution.

 

The Yocto project is the most widely supported system for building custom Linux distributions.
The Yocto project is very well supported by both communities and companies.  The project consists of a tool called bitbake and a build system that is based off of OpenEmbedded.  Together, these two components along with a defined set of metadata comprise what is called the Poky reference platform.

Yocto supports numerous architectures through OpenEmbedded. These include x86, ARM®, MIPS, and PowerPC.  Yocto's most attractive feature is its support of what are called layers.  Layers allow the abstraction of individual components or sets of components within a board support package (BSP). New layers can be derived from existing layers to enhance functionality, patch source code, or remove subsets of unneeded components.  

Building support for a custom boot loader, custom kernel, custom rootfs, and development application layer is both very clean and straightforward.  SELinux has become a necessary component of almost every Linux distribution.  It is very simple to integrate SELinux into Yocto via an OpenEmbedded layer.   Consequently, building a "Carrier Grade" Linux distribution for one of the many (several hundred) processors is attainable in a short amount of time.

Embest Technology created the RIoTboard.  The board design is fairly simple.  The board contains an i.MX 6 Solo processor.  Embest Technology and Element 14 provide links to download prebuilt Linux and Android images.  Embest Technology also has a github repository where source code can be downloaded to build a complete BSP.  The complete BSP consists of the u-boot boot loader, kernel, and root filesystem.

Embest Technology took a snapshot of the Freescale Community BSP Platform source code repository at some point in the past.  The BSP source download from github, which consists of the Yocto layers for building a riotboard BSP, is not up to date with Freescale, Yocto, and OpenEmbedded.

Consequently, Freescale's community BSP platform will be used.  The platform is comprised of both the Poky reference build system and an additional series of layers which will allow us to build a custom Linux distribution for the i.MX 6 processor architecture.  

A custom Linux distribution that will be used for development should include support for only the peripheral components that will be used. The custom development distribution should be minimized to the maximum extent possible.  All I/O interfaces should be clearly documented.  Bootable media types should be documented and partition maps should be created.  These steps greatly ease development and debugging, and prevent unknown issues from cropping up after production release.  Layering in SELinux at a later time is simple.  Creating new layers for shared library development, or userspace application development is also simple and layers can be added for slicing out pieces of the kernel that aren't now, but may be needed later on.  Last but not least, blowing the appropriate fuses prior to production is critical.

To keep things simple, a new BSP or custom Linux distribution will be derived from the riotboard specifications that have already been incorporated into Freescale's community BSP platform.  

The goal here is to produce a minimal Linux distribution that can be used for development and easily extended from any level in the stack - u-boot, kernel, root filesystem, and userspace libraries or executables.  Most importantly, the architecture of this distribution will conform to the standards that have been outlined by the Yocto Project and OpenEmbedded.  This means anyone can easily pick up.

The input specifications for a generic i.MX 6 solo machine have been mostly documented in the meta-fsl-arm-extra layer.  The output image that is produced from these input specifications is an image that consists of the u-boot boot loader, i.MX 6 Solo/Dual kernel, and ext3 root filesystem.
In an effort to build a custom Linux distribution for the i.MX 6 Solo/Dual with the least amount of packages in the shortest amount of time, slimming down the input specifications, configuring the distribution, and naming it should only require modification of a few files.  Here are the steps.

First, the riotboard or target must be connected to the Fedora 20 x86_64 host via serial UART (see last blog post).  A card reader must be connected to the host via USB. 

The new distribution will be called the bsec distribution.  The bsec distribution will consist of a minimal Linux image, u-boot boot loader, and ext3 root filesystem configured for the i.MX 6 based riotboard.

Perform the following steps on the host.

1.  Pull the Freescale community BSP platform source code from github.  Dizzy is the Yocto 1.7.1 branch.   Execute the following commands on the host.

 $ mkdir $HOME/bin  
$ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
$ chmod a+x $HOME/bin/repo
$ echo "PATH=$PATH:$HOME/bin" >> $HOME/.bashrc
$ source .bashrc
$ mkdir -p $HOME/src/fsl-community-bsp
$ cd $HOME/src/fsl-community-bsp
$ repo init -u https://github.com/Freescale/fsl-community-bsp-platform -b dizzy
$ repo sync

2.  Setup the build environment using the predefined imx6dl-riotboard machine.

 $ MACHINE=imx6dl-riotboard . ./setup-environment build  

3.  Create a new layer for the custom Linux distribution

 $ cd $HOME/src/fsl-community-bsp/sources  
$ mkdir -p meta-bsec/conf/distro
$ mkdir -p meta-bsec/recipes-bsec/images
$ cd poky/meta/recipes-core/images
$ cp core-image-minimal.bb ../../../../meta-bsec/recipes-bsec/images/bsec-image.bb

4.  Create the layer.conf file in the meta-bsec layer. 

sources/meta-bsec/conf/layer.conf should contain the following
 BBPATH .= ":${LAYERDIR}"  
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
${LAYERDIR}/recipes-*/*/*.bbappend"
BBFILE_COLLECTIONS += "bsec"
BBFILE_PATTERN_bsec = "^${LAYERDIR}/"
BBFILE_PRIORITY_bsec = "6"

5.  Create the distribution configuration file in the meta-bsec layer. 

sources/meta-bsec/conf/distro/bsecdist.conf should contain the following
 require conf/distro/poky.conf  
DISTRO = "bsecdist"
DISTRO_NAME = "bsecdist distribution"
DISTRO_VERSION = "1.0"
DISTRO_CODENAME = "bsc"
SDK_VENDOR = "-bsecdistsdk"
SDK_VERSION := "${@'${DISTRO_VERSION}'.replace('snapshot-${DATE}','snapshot')}"
MAINTAINER = "bsecdist <e-mail-address>"
INHERIT += "buildhistory"
BUILDHISTORY_COMMIT = "1"

6.  Added the new layer to bblayers.conf

build/conf/bblayers.conf should contain the following
 LCONF_VERSION = "6"  
BBPATH = "${TOPDIR}"
BSPDIR := "${@os.path.abspath(os.path.dirname(d.getVar('FILE', True)) + '/../..')}"
BBFILES ?= ""
BBLAYERS = " \
${BSPDIR}/sources/poky/meta \
${BSPDIR}/sources/poky/meta-yocto \
\
${BSPDIR}/sources/meta-openembedded/meta-oe \
${BSPDIR}/sources/meta-openembedded/meta-multimedia \
\
${BSPDIR}/sources/meta-fsl-arm \
${BSPDIR}/sources/meta-fsl-arm-extra \
${BSPDIR}/sources/meta-fsl-demos \
${BSPDIR}/sources/poky/meta-selinux \
${BSPDIR}/sources/meta-bsec \
"

7.  Set the distribution to the bsec distribution in local.conf

build/conf/local.conf should contain the following
 MACHINE ??= 'imx6dl-riotboard'  
DISTRO ?= 'bsecdist'
PACKAGE_CLASSES ?= "package_rpm"
EXTRA_IMAGE_FEATURES = "debug-tweaks"
USER_CLASSES ?= "buildstats image-mklibs image-prelink"
PATCHRESOLVE = "noop"
BB_DISKMON_DIRS = "\
STOPTASKS,${TMPDIR},1G,100K \
STOPTASKS,${DL_DIR},1G,100K \
STOPTASKS,${SSTATE_DIR},1G,100K \
ABORT,${TMPDIR},100M,1K \
ABORT,${DL_DIR},100M,1K \
ABORT,${SSTATE_DIR},100M,1K"
PACKAGECONFIG_append_pn-qemu-native = " sdl"
PACKAGECONFIG_append_pn-nativesdk-qemu = " sdl"
ASSUME_PROVIDED += "libsdl-native"
CONF_VERSION = "1"
BB_NUMBER_THREADS = '1'
PARALLEL_MAKE = '-j 1'
DL_DIR ?= "${BSPDIR}/downloads/"
ACCEPT_FSL_EULA = "1"

8.  Pull the OpenEmbedded SELinux meta layer for later configuration

 $ cd sources/poky   
$ git clone -b dizzy git://git.yoctoproject.org/meta-selinux
$ cd ../..

9.  Perform the build

 $ cd build  
$ bitbake bsec-image

10.  Write the image to the SD card

 $ cd tmp/deploy/images/imx6dl-riotboard  
$ sudo dd if=bsec-image-imx6dl-riotboard.sdcard of=/dev/sdX bs=1M
$ sudo sync

At this point, the jumpers on the riotboard should be set to boot from the SD card.  Next, power on the riotboard with the new SD card.  If HDMI is connected,  the Das u-boot software engineering logo should appear on the display.

 bsecdist distribution 1.0 imx6dl-riotboard /dev/ttymxc1               
imx6dl-riotboard login:

Review the input specifications for the riotboard machine should be simple.  Start with the following files

 sources/meta-fsl-arm-extra/conf/machine/imx6dl-riotboard.conf  
sources/poky/meta-yocto/conf/distro/poky.conf
sources/meta-fsl-arm/recipes-kernel/linux/linux-imx.inc
sources/meta-fsl-arm/recipes-kernel/linux/linux-fslc_3.17.bb
sources/poky/meta/conf/machine/include/tune-cortexa9.inc

The input specifications for this image are raw and generic. They define software support for ALL of the on-board peripherals with the e-fuses left open.

Finally, the output image was 29 MB and is comprised of the u-boot boot loader, the Linux kernel, and the root file system.  This is a decent place to start before adding more software to the BSP.

Tuesday, December 23, 2014

Setting up an ARM® Cortex®-A9 based SBC

The RiOTboard - an ARM® Cortex®-A9 based SBC

The RIoTboard is an ARM® Cortex®-A9 based single board computer (SBC).  The RIoTboard has a Freescale i.MX6 Solo application processor and an integrated Freescale Kinetis MCU for additional debugging and development.  The i.MX6 Solo supports the single ARM® Cortex®-A9 MPCore Platform.  The i.MX6 Solo contains ARM® TrustZone® technology and the i.MX 6 SoC on the RIoTboard has a 96 KB Boot Rom with support for high assurance boot.   Other features of the board include 1 GB of DDR3 memory, 4 GB eMMC, JTAG, Serial, mini USB for OpenSDA, mini USB for USB OTG, LVDS, parallel RGB expansion, 4 USB-A ports, HDMI, audio, reset button, microSD card slot, SD card slot, and boot onboard boot switches.   The board is very reasonably priced.  Last but not least, the Freescale i.MX 6 ARM® Cortex®-A9 application processor has ARM® TrustZone® technology.


Trusted Zone

ARM® TrustZone® Technology

The i.MX6 Solo processor on the RIoTboard is labeled MCIMX6S8DVM10AB.  According to the i.MX6 Solo data sheet, the processor supports a number of security related features. The list includes ARM® TrustZone® technology with TZ architecture support, a secure JTAG controller for locking down and protecting the JTAG port, a cryptographic acceleration and assurance module with secure RAM and a true PRNG, a central security unit (CSU) including secure non-volatile storage, high assurance boot, and the separation of memory and interrupts between secure world and normal world.  There are more security related features but this is a general list.


Setting up a RIoTboard

Embedded devices used for development purposes often have network controllers on them.  From mobile phones to radios, routers, watches, and wearables, these devices are sending and receiving IP datagrams to external Internet hosts via one or many of their network interfaces; WiFi, 3G, 4G, and Bluetooth.  Most of the processors being sold today can run rich operating systems with full software support for multiple network interface controllers.  In addition, many of the processors being sold today contain support for both virtualization and trusted execution. 

A network router that is isolated from the Internet and any local computers can be connected to the embedded device via the device's primary network interface. If there are multiple network interfaces on the embedded device, then multiple routers can be connected to the embedded device - one for each interface type. 3G and 4G routers, while not widely available, can be connected to the 3G or 4G modem on the embedded device.

IP traffic can be sent and received from both secure world and normal world via multiple network interfaces.  Raw packet analysis tools on the router can be used to inspect incoming and outgoing traffic from the embedded device.  After the router is connected to the embedded device, data that is transmitted over the embedded device's network interface can be recorded to a format such as PCAP and saved for later analysis.  A firewall can also be deployed on the router and all outgoing traffic originating from the embedded device can be blocked.  Inexpensive routers with ARM® based processors and ARM® TrustZone® technology can be purchased from most retail stores.

Short of having access to JTAG hardware debuggers, a Bus Pirate can be used in conjunction with OpenOCD for debugging the i.MX 6 processor on the RiOTboard.  A bus pirate can also be used in transparent UART bridge mode for connecting the host to the target (the RiOTboard).

This type of setup can be very useful for debugging embedded devices, analyzing embedded devices, developing software for embedded devices, and testing embedded devices prior to production.


The Netgear WNR3500U (right) can run multiple rich operating systems.


  • Digital multimeter for testing continuity of JTAG, SWD, and Serial cables
  • Proper ground and wrist strap
  • 2x ethernet cable
  • WNR3500U router
  • microSD card 8 GB Class I
  • SD card 8 GB Class I
  • RiOTboard
  • 5 VDC power supply for RiOTboard
  • 2x Bus Pirate
  • Cortex SWD 10 to 20 pin adapter
  • 2x 5-pin female to female breakout cable
  • FTDI mini USB to 5-pin female breakout board
  • 4-pin female to female breakout cable
  • HDMI cable
  • USB mouse
  • USB keyboard
  • Display
  • Host computer with Linux (Fedora 21)
  • 4x mini USB to USB-A cables
  • 10-pin female to female SWD / JTAG cable
  • Card reader

Using the Bus Pirate as a transparent UART bridge

Bus Pirate Pin 01 GND  <---> RiOTboard J18 Pin 3 GND
Bus Pirate Pin 08 MOSI <---> RiOTboard J18 Pin 1 UART2 TX
Bus Pirate Pin 10 MISO <---> RiOTboard J18 Pin 2 UART2 RX

Flashing the PIC on the Bus Pirate is straightforward (see documentation) and should be performed so that the Bus Pirate is running the latest firmware.

RiOTboard connected via JTAG and UART to Host




Monday, December 15, 2014

ARM, NFC Technology, and the Single Wire Protocol

At the heart of an ARM Powered® smartphone with NFC technology is the contactless front end or CLF. The CLF is responsible for managing radio-frequency communication at 13.56 MHz. 


A mobile phone with NFC technology contains only one CLF. The CLF is connected to the ARM® processor or application processor via UART, I²C, and SPI. These protocols are relatively basic and facilitate straightforward communication between the application processor and CLF via a typical Linux or UNIX-based kernel. Updating the firmware on the CLF is a typical operation performed over the UART serial line. 


While a mobile phone with NFC technology contains only one CLF, the phone may contain multiple secure elements. A secure element may reside on the UICC card, on the microSD card, or embedded with the CLF on the PCB. Applets residing on each of the secure elements can serve both similar and different purposes. Both the secure element and the CLF are small, self-contained computers with I/O communications interfaces. In the case where multiple secure elements reside on the phone, each of the secure elements is a small, self-contained computer with I/O communication interfaces. A secure element differs from a normal computer in that it is embedded and has limited resources available for performing computations. 


A typical secure element also contains dedicated hardware co-processors for performing common cryptographic operations. Implementing standard cryptographic algorithms at the software level on the secure element is not always practical due to the resource constraints of the secure element components. At a high level, the applet(s) 's responsibility resides on the secure element is to handle the secure storage and transmission of private data. For these types of use cases, encryption and decryption are common operations. Consequently, they are refactored into hardware blocks on most secure elements.


UICC-based SEs, eSEs, and microSD-based SEs all use cryptography to store private data. UICC-based SEs, eSEs, and microSD-based SEs are typically manufactured by different companies. Consequently, multiple types of operating systems run on secure elements.


When the secure element is packaged with the CLF on the PCB, it is called the embedded secure element (eSE). The eSE is connected to the CLF via S2C (NFC-WI) for such a configuration.

By design, the inclusion of the embedded SE into the IC package with the CLF means that the provisioning of trusted applets, such as those used for e-ticketing, can occur via a communications channel external to that of the carrier-controlled, baseband processor. Updates and network communication with a UICC-based SE occur via the baseband processor. On the contrary, an eSE is not typically provisioned by the MNO when the phone is purchased. If the user has access to the proper access keys, communication with an embedded SE (eSE) can occur via the CLF through the application processor. The eSE is connected to the CLF in the IC package via the S2C bus. The S2C or NFC-WI interface was initially proposed by Philips and subsequently standardized by ECMA. The S2C interface consists of two lines, SigIn and SigOut, implemented as two physical wires between the CLF and embedded secure element. This S2C protocol allows for full-duplex communication over two physical wires between the CLF and eSE. A common eSE is called the NXP SmartMX.


In contrast, the UICC on a mobile phone has traditionally been used by the mobile network operators (MNOs) for carrier-specific purposes such as network subscriber information. Mobile phones with NFC technology and a UICC also utilize the secure element on the UICC for e-ticketing applications. The MNOs have primarily been involved in utilizing the secure element on the UICC for storing private data. The UICC-based SE manufacturer is most likely some entity other than NXP. The applets that reside on the UICC-based SE are inherently the domain of the mobile network operators. Applets running on the UICC are used for multiple purposes, including carrier network and subscriber information and NFC  e-ticketing applications. Applications responsible for storing private data are provisioned by trusted external entities associated with the MNOs. Currently, the UICC-based SE is provisioned by a trusted MNO entity prior to purchase. Carrier network activities such as call initiation and SMS receipt can be communicated to/from applets running on the UICC via the radio interface software layer running on the application processor's operating system as the application processor is connected to the baseband processor. This exchange occurs in the form of APDUs. APDUs are exchanged between a contactless point of sale terminal and an applet running on the UICC-based SE or eSE during an NFC e-ticketing activity.


Since the inception of NFC hardware on ARM Powered® smartphones, NFC e-ticketing applets have been added to the secure element on the UICC. The UICC is physically connected to the phone's baseband processor. The UICC is connected to the CLF via the single wire protocol (SWP) for a phone with NFC technology. A single, physical wire is connected between the CLF and one of the contact pins on the UICC. SWP defines the connection between the UICC and CLF. SWP is intended for use when the UICC-based SE houses trusted applets responsible for e-ticketing applications and private data storage. SWP allows full-duplex communication over a single physical wire between the CLF and UICC. ETSI TS 102 613 defines the physical and data layers of SWP. SWP was established by Gemplus (now Gemalto).


In the United States, MNOs utilize the secure element on the UICC card for hosting e-ticketing applications and storing private data. Android phones with NFC technology may an application that uses the RF controller on the phone. If this is the case, the phone most likely contains a UICC-based secure element connected to the internal CLF via the SWP.


The mobile phone may contain an NXP PN544 pin-to-pin compatible PN65N, in which case, the SWP line is wired to the UICC SWP contact pin via a single physical wire. Alternatively, the phone may contain a PN544 CLF, in which case the same SWP line is wired to the UICC SWP contact pin via a single physical wire. When an embedded secure element is connected to the CLF via S2C (NFC-WI) and the CLF is also connected to the UICC-based SE over the single wire protocol (SWP), then applications (applets) can be selected by id from either secure element.


The provisioning of applets to either the eSE, microSD SE, or UICC-based SE occurs via different channels. The MNOs have primarily been responsible for the provisioning of applets to the UICC-based SE via trusted third parties. In contrast, device manufacturers can provision parts of the embedded secure element before it leaves the factory. The physical connection to the secure element is one of its key differentiating factors. Embedded secure elements are connected to the CLF via S2C. In contrast, UICCs use the SWP pin to connect with the CLF. When an e-ticketing transaction occurs via NFC, it does so over the contactless communication interface. The remote e-ticketing terminal sends information back and forth between the applet running on the secure element. This communication occurs via the CLF to the SE, either over the single wire connection to a UICC-based SE or over the two-wire (S2C) connection to the eSE; depending on which SE is running the issuers e-ticketing applet. The MNO may provision the UICC-based SE with special applications. The microSD card is also connected to the CLF; however, this is not mentioned since microSD-based secure elements are not as prevalent yet in the United States.


It has been the intent of the OEMs (not all), silicon manufacturers (not all), and those in favor of open ecosystems to utilize the onboard embedded secure element (eSE) for hosting the applications that are responsible for e-ticketing applications.


There are multiple parties involved in this ecosystem; they include and are not limited to trusted third parties responsible for provisioning applets to the secure element via the carrier network, credit card issuers, silicon manufacturers, original equipment manufacturers (OEMs), banks, mobile network operators (MNOs), software vendors such as Google, credit card manufacturers, credit card issuers global standards bodies such as ISO and EMVCo, trusted service managers, service providers, certificate authorities, industry associations such as Global Platform, and numerous regulating entities. The ecosystem is complex, and there are currently several successful efforts underway to standardize NFC technology and how it is used in the United States.


As a critical point to consider and in contrast to the solutions that have been implemented for the safe execution and storage of NFC related  e-ticketing applications and private data, ARM® TrustZone® technology in the processor core can be utilized in a similar light to that of the technologies on the eSE, UICC-based SE, and microSD SE. ARM® TrustZone® technology provides an ideal platform for secure keypad entry and user authentication.


ARM and Cortex are registered trademarks of ARM Limited (or its subsidiaries) in the EU and/or elsewhere. All rights reserved. ARM and TrustZone are registered trademarks of ARM Limited (or its subsidiaries) in the EU and/or elsewhere. All rights reserved. ARM and SecurCore are registered trademarks of ARM Limited (or its subsidiaries) in the EU and/or elsewhere. All rights reserved. ARM and Keil are registered trademarks of ARM Limited (or its subsidiaries) in the EU and/or elsewhere. All rights reserved.Freescale, the Freescale logo, AltiVec, C-5, CodeTEST, CodeWarrior, ColdFire, ColdFire+, C-Ware, the Energy Efficient Solutions logo, Kinetis, MagniV, mobileGT, PEG, PowerQUICC, Processor Expert, QorIQ, QorIQ Qonverge, Qorivva, Ready Play, SafeAssure, the SafeAssure logo, StarCore, Symphony, VortiQa, Vybrid and Xtrinsic are trademarks of Freescale Semiconductor, Inc., Reg. U.S. Pat. & Tm. Off. SMARTMX is a trademark of NXP B.V. SMARTMX2 is a trademark of NXP B.V. JCOP is a trademark of NXP B.V. Android is a trademark of Google, Inc. QNX and Neutrino are registered trademarks of QNX Software Systems Ltd. IOS is a trademark or registered trademark of Cisco in the U.S. and other countries.

Friday, December 12, 2014

ARM Powered® smartphones with NFC technology

 

Turing machines, first described by Alan Turing in (Turing 1937), are simple abstract computational devices intended to help investigate the extent and limitations of what can be computed.  - Stanford Encyclopedia of Philosophy

The head and the tape in a turing machine


There are many Near field communication (NFC)-enabled phones (devices) on the consumer market. LG, Huawei, Motorola, Samsung, HTC, Nokia, ZTE, Sony, RIM, Amazon, and Apple manufacture and sell mobile phones with NFC technology.


There are many common denominators at the hardware and software levels between all of the phones that have NFC technology. First, all mobile phones contain a main (application) processor, and if the phone is manufactured by one of the companies listed above, the application processor is an ARM® microprocessor. There may be one or two exceptions, but if 150 current phones were sampled across all of these manufacturers, one would find that 99% of the phones contain ARM® technology. Operating systems that run on the ARM Powered® processors contained within phones from these manufacturers are similar in that they support preemptive multitasking. Most of these devices run the Linux operating system or a UNIX-based operating system.

 

An ARM Powered® smartphone with NFC technology contains other microprocessors on its printed circuit board (PCB). These other microprocessors consist of the radio frequency (RF) controller or contactless front end (CLF) and an optional embedded secure element (eSE). The CLF is responsible for managing contactless communication at 13.56MHz. The eSE and SE (external UICC-based or microSD card-based) are responsible for secure application execution and the secure storage of sensitive payment or identification information. A trusted OS runs on the eSE and/or SE. A mobile phone may contain both an eSE and a UICC-based or microSD-based SE. For such a configuration where multiple secure elements exist on the phone, different trusted operating systems may run on the phone's secure elements, and different trusted applications (client applications) may run on the trusted operating systems. One trusted application may be responsible for secure VISA payments, and another trusted application may be responsible for electronic identification (eIdentification).


The RF controller and the embedded secure element (eSE) are soldered directly to the PCB, typically within the same IC package. The RF controller may exist on the circuit board without the eSE. The eSE is an optional hardware component on a mobile phone that contains NFC technology. The RF controller and eSE are soldered to the PCB by the phone manufacturer. Alternatively, the secure element used for NFC may be external. An external secure element is one that is located on the mobile phone's UICC or microSD card. When a mobile phone is purchased from a local cell phone store, a UICC card is usually inserted into the phone by the person at the store. If purchased from one of the leading operators in the United States, the UICC card contains a secure element. It is important to note that the existence of an embedded secure element and a UICC-based or microSD-based secure element on the same mobile phone are not mutually exclusive. The secure elements may serve different purposes.

 

As mentioned above, ARM Powered® smartphones with NFC technology may contain a single type of secure element. Such a phone may only contain a CLF or RF controller. Mobile phones with a CLF and no secure element may emulate the software running on the secure element via the operating system and application software running on the application processor. This is called host card emulation (HCE).


There are numerous configurations of NFC technology on mobile phones. Each of the components described exposes one or more hardware interfaces for communication and interconnection with neighboring components on the printed circuit board. Hardware bus protocols and software communication protocols run on top of the wires that connect the individual components on the printed circuit board. These include standard bus protocols such as I²C, S2C (NFC-WI), SWP, and SPI. (more on this later). It is important to note that a typical ARM Powered® smartphone with NFC technology has a CLF that is connected to the application processor via both I²C and UART. This is good because I²C device drivers are not complicated and reading/writing to a tty on an ARM Powered® smartphone is straightforward. Lastly, the CLF typically contains an optimized 80C51 processor. The CLF may be packaged with a secure element and the secure element may contain an optimized 8051 core or newer RISC based core. The secure element will also contain dedicated crypto co-processors for performing asymmetric or symmetric cryptographic operations (i.e. FameX). Custom firmware runs on the CLF, and it can usually be updated via the host operating system over UART. 80C51 firmware for the CLF is usually C code. (more on this later). A trusted OS (e.g., JCOP) and trusted applications (applets) run on the secure element. Lastly, if the CLF and secure element are contained within a single IC soldered onto the PCB, they are usually connected via S2C (NFC-WI) internally. As a side note, ARM® designs and manufactures ARM® Keil® development boards. Arm® Keil® and Ashling are two of the most prevalent companies that sell compilers and development toolkits for embedded microprocessors such as the 80C51. Ashling sells an excellent series of in-circuit emulators (ICE) for debugging SmartMX and SmartMX2 microcontrollers.

 
 
The architectural variations of the NFC hardware technology contained within current mobile phones can be summarized as follows. The most common configurations are at the top.  It has come to my attention that several of the card issuers have tested the microSD SE configuration on certain phones. The authenticity of which handsets have the physical S2C or SWP wiring between the microSD card and CLF cannot be validated, so the last column contains a -.

Application ProcessorApplication Processor OSCLFeSEUICC SEmicroSD SE
ARM Powered® iOSYESYESNO-
ARM Powered®AndroidYESYESYES-
ARM Powered®AndroidYESNOYES-
ARM Powered®AndroidYESYESNO-
ARM Powered®QNXYESYESYES-
ARM Powered®QNXYESNOYES-

ARM and Cortex are registered trademarks of ARM Limited (or its subsidiaries) in the EU and/or elsewhere. All rights reserved. ARM and TrustZone are registered trademarks of ARM Limited (or its subsidiaries) in the EU and/or elsewhere. All rights reserved. ARM and SecurCore are registered trademarks of ARM Limited (or its subsidiaries) in the EU and/or elsewhere. All rights reserved. ARM and Keil are registered trademarks of ARM Limited (or its subsidiaries) in the EU and/or elsewhere. All rights reserved.Freescale, the Freescale logo, AltiVec, C-5, CodeTEST, CodeWarrior, ColdFire, ColdFire+, C-Ware, the Energy Efficient Solutions logo, Kinetis, MagniV, mobileGT, PEG, PowerQUICC, Processor Expert, QorIQ, QorIQ Qonverge, Qorivva, Ready Play, SafeAssure, the SafeAssure logo, StarCore, Symphony, VortiQa, Vybrid and Xtrinsic are trademarks of Freescale Semiconductor, Inc., Reg. U.S. Pat. & Tm. Off. SMARTMX is a trademark of NXP B.V. SMARTMX2 is a trademark of NXP B.V. JCOP is a trademark of NXP B.V. Android is a trademark of Google, Inc. QNX and Neutrino are registered trademarks of QNX Software Systems Ltd. IOS is a trademark or registered trademark of Cisco in the U.S. and other countries.

Monday, December 8, 2014

The ARM Cortex-A9 Processor - Real World Uses

The ARM® Cortex®-A processor is found in compute-intensive applications.  ARM® Cortex®-A processors run full or rich operating systems such as Linux or UNIX.  I mentioned the ARM® Cortex®-A9 based MPCore in the last blog post.  The ARM® Cortex®-A9 processor processor is highly configurable.

Freescale Semiconductor implements an ARM® Cortex®-A9 processor called the i.MX 6.  Freescale sells the i.MX 6 processor in a lite, single, dual, dual-lite, and quad-core configuration. The i.MX 6 processor is used in critical applications across multiple industries.  These industries include aerospace, medical, and industrial.  i.MX processors can be found in Medical-CT scanners, ultrasound machines, automotive telematic systems, airplane computers, e-readers, and a host of other devices.  The power efficiency characteristics of the i.MX 6 make them attractive for wearables such as eye glasses and watches.

The OrCam, powered by the i.MX 6, is a clip-on wearable designed for users with vision impairments. The OrCam clips-on to a pair of eye glasses and continually scans the user's field of vision, detecting objects, and providing aural feedback via a bone conduction ear piece. For a quick overview of the OrCam, the following video is worth watching

OrCam Powered by Freescale i.MX 6Quad Processor and PMIC

The Kindle Fire HD 6 tablet also has an i.MX 6 processor.  Keep an eye out for wearables, watches, and glasses that have an i.MX 6 processor.

When it comes to development, the i.MX 6 is almost ideal.  The manuals and data sheets for the processor are very long. However; the one time programmable memory locations or eFuses on the i.MX 6 are highly configurable.  eFuses are standard in higher end microprocessors. The eFuses can be read or blown (one-time write to an on-chip memory location) via u-boot or the Freescale manufacturing tool.  They can also be pulled via the Linux sysfs interface.  There are over typically over 100 eFuses on higher end microprocessors.  A few of the important values that are stored in one-time programmable memory (eFuses) include the MAC address, boot configuration parameters, high-assurance boot (HAB) configuration parameters, and master key.  As a side note, many chips have on-chip memory locations that can only be written to one time.  U-boot conveniently supports reading and writing (blowing) the eFuses on many different microprocessors.  U-boot is open source and it supports one-time programmable memory (eFuses or OTP) on ARM®-based processors.  The U-Boot boot loader supports a large number of chip sets; including ARM®, AVR32, Blackfin, MicroBlaze, MIPS, PPC, and x86.

ARM and Cortex are registered trademarks of ARM Limited (or its subsidiaries) in the EU and/or elsewhere. All rights reserved.  ARM and TrustZone are registered trademarks of ARM Limited (or its subsidiaries) in the EU and/or elsewhere. All rights reserved.  ARM and SecurCore are registered trademarks of ARM Limited (or its subsidiaries) in the EU and/or elsewhere. All rights reserved. Freescale, the Freescale logo, AltiVec, C-5, CodeTEST, CodeWarrior, ColdFire, ColdFire+, C-Ware, the Energy Efficient Solutions logo, Kinetis, MagniV, mobileGT, PEG, PowerQUICC, Processor Expert, QorIQ, QorIQ Qonverge, Qorivva, Ready Play, SafeAssure, the SafeAssure logo, StarCore, Symphony, VortiQa, Vybrid and Xtrinsic are trademarks of Freescale Semiconductor, Inc., Reg. U.S. Pat. & Tm. Off.

Sunday, December 7, 2014

ARM TrustZone® technology - from Monitor Mode to Dedicated Security Co-Processing and the Secure Element(s)



The ARM® TrustZone® technology Web page defines TrustZone as

A design that places the sensitive resources in the Secure world, and implements robust software running on the secure processor cores, can protect assets against many possible attacks, including those which are normally difficult to secure, such as passwords entered using a keyboard or touch-screen. By separating security sensitive peripherals through hardware, a designer can limit the number of sub-systems that need to go through security evaluation and therefore save costs when submitting a device for security certification. - ARM.com
NOTE: there are variations on how software is implemented in secure world - from a simple synchronous library of code to a full blown operating system.

The execution of the normal OS and secure OS is interleaved over time via a context-switching mechanism called monitor mode. Monitor mode is responsible for time-slicing the execution of the normal OS and secure OS via context switching the state of each world on the physical processor. Monitor mode is explicitly triggered via a dedicated instruction or special type of exception. The explicit methods by which monitor mode is triggered contrast the typical scheduling algorithms that trigger context switching in modern day preemptive operating systems.

There are varying levels of complexity in regards to how the physical hardware in which secure world runs on is designed. These range from both worlds running on the same physical processor core to secure world running on a completely separate processor core.

Another type of physical hardware design entails an additional microprocessor that is separate from the main processor. The secure world software stack (secure OS and secure applications) is run on a dedicated co-processor. This design is not exclusive to a secure OS running on the main ARM® processor. The normal OS still runs on the main ARM® processor, and a secure OS can still run on the main ARM® processor if the main ARM® processor has ARM® TrustZone® technology. A different secure OS and secure application software can run on the dedicated co-processor. 

Client applications running on a secure OS can communicate with the main ARM® processor via a set of APIs and commands. There are certain benefits to the secure OS always running on a dedicated security processor core or co-processor. 

The operating system that runs on the co-processor can be optimized for just the co-processor. There are many types of dedicated co-processors. The ARM® SecurCore® microprocessor is one type of dedicated co-processor. ARM® SecurCore® microprocessors are used in systems that require dedicated processors for security-sensitive applications such as SIM cards, e-Government, Banking, and Identification. Designs that incorporate ARM® SecurCore® microprocessors can realize multiple key benefits including build performance improvements, energy efficiency, and physical security. Designing and building an operating system for a single chip means that the operating system can be built to use all of the features and only those features that the chip provides.

In summary, here are the key points:
  • Operating system software runs on the main ARM® processor or application processor.
  • Software applications run on the application processor.
  • ARM® processors in ARM®-based mobile phones may or may not have ARM® TrustZone® processor security technology.  If the ARM® processor has ARM® TrustZone® processor security technology, then it may or may not be used.
  • There are additional processors on mobile phones that act as dedicated security co-processors. These include the secure element on the UICC or SIM card (UICC based SE) and the secure element that has been soldered on the printed circuit board.  The secure element that has been soldered to the printed circuit board is called the embedded SE.  The iPhone® 6, an iPhone® 6 Plus, Samsung S5, Galaxy Nexus, Nexus S, Nexus 7, Sony Xperia series, and a host of others contain a secure element soldered onto the printed circuit board.  If the phone has a secure element that has been soldered onto the printed circuit board, then it is most likely contained within the packaging of a larger SoC that also contains the Near field communication (NFC) Radio-Frequency (RF) controller.  Last but not least, it is entirely possible that the phone contains a secure element on the microSD card.
  • The embedded SE and UICC based SE run a trusted OS.  Trusted applications run on top of the trusted OS.  In contrast to the trusted OS that runs within secure world on a main ARM processor with ARM® TrustZone® processor security technology, the trusted OS that runs on the embedded SE and UICC based SE does not share full hardware peripheral or direct normal world software access on the main application processor.
  • The UICC based SE and embedded SE are protected by cryptographic keys.  Client software applications running on the trusted OS in a processor with ARM® TrustZone® architecture security extensions are also protected by cryptographic keys.
  • There are multiple standards bodies that have established APIs, architecture documents, design documents, and so-forth for the trusted operating system and trusted applications that run on the UICC based SE and embedded SE.  These entities are also responsible for the hardware interface on the physical secure element.
NOTE: This was a high-level, technical overview.

ARM and Cortex are registered trademarks of ARM Limited (or its subsidiaries) in the EU and/or elsewhere. All rights reserved. ARM and TrustZone are registered trademarks of ARM Limited (or its subsidiaries) in the EU and/or elsewhere. All rights reserved. ARM and SecurCore are registered trademarks of ARM Limited (or its subsidiaries) in the EU and/or elsewhere. All rights reserved. Freescale, the Freescale logo, AltiVec, C-5, CodeTEST, CodeWarrior, ColdFire, ColdFire+, C-Ware, the Energy Efficient Solutions logo, Kinetis, MagniV, mobileGT, PEG, PowerQUICC, Processor Expert, QorIQ, QorIQ Qonverge, Qorivva, Ready Play, SafeAssure, the SafeAssure logo, StarCore, Symphony, VortiQa, Vybrid and Xtrinsic are trademarks of Freescale Semiconductor, Inc., Reg. U.S. Pat. & Tm. Off. iPhone is a trademark of Apple Inc., registered in the U.S. and other countries.

ARM TrustZone technology - a Few Good Boards

ARM® provides a reference platform for software and hardware developers building systems based on ARM® Cortex®-A processors. The system is called the Juno ARM® Development Platform. The platform ships with a board that contains an ARM® Cortex®-A57 processor and ARM® Cortex®-A53 MPCore processor. The ARM® Cortex®-A57 processor and ARM® Cortex®-A57 processor are 64-bit and implement the ARM®v8-A instruction set architecture (ISA). A board support package can be built for this board using OpenEmbedded / Yocto.


The Apple® A7 and Apple® A8 chips in the iPhone® 5c, iPhone® 5s, iPhone® 6, and iPhone® 6 Plus are based on the ARM® Cortex®-A53 and ARM® Cortex®-A57. The Samsung Exynos 5433 Octa SoC also has an ARM® Cortex®-A57 and ARM® Cortex®-A53 MPCore. The Samsung Galaxy Note 4 has an 8-core Exynos 5433 processor in it.


Another development board is the Nvidia TK1 development board. This board has a quad-core ARM® Cortex®-A15 processor. These boards have been available for purchase at local retailers lately. However, the Nvidia K1 "Denver" is the latest product that they are working on and is not available for purchase yet. It is rumored that the project "Denver" board has an ARM® Cortex®-A57 and an ARM® Cortex®-A53 MPCore.


The Freescale I.MX 6 processor has been hugely popular across many industries in a variety of embedded products. Freescale sells a development board with the I.MX 6 processor on it. The board is called the SABRE board for intelligent devices. The SABRE board has a Freescale I.MX 6 Quad-Core ARM® Cortex®-A9 processor. Other vendors on the Internet sell their variation of this development board. One example is Boundary Devices. They sell their version of this board with the same Freescale I.MX 6 Quad-Core ARM® Cortex®-A9 MPCore. A board support package can be built for both the Freescale SABRE board and the Boundary Devices board using OpenEmbedded / Yocto.


A few critical features of ARM development boards should be taken into account. Namely, the e-fuses should not be blown out of the box, and they should be left open. The fuses can be blown to fit a specific configuration. 


Here is a quick overview of the processors and boards.


Processor
Manuf
ISA
Dev Board
TrustZone
ARM® Cortex®-A57 and ARM® Cortex®-A53 MPCoreARM®ARM®v8-AJuno Ref PlatformYes
ARM® Cortex®-A15NvidiaARM®v7TK1Yes
ARM® Cortex®-A15SamsungARM®v7Arndale Exynos 5420Yes
ARM® Cortex®-A9 MPCoreFreescaleARM®v7Freescale SABREYes
ARM® Cortex®-A9 MPCoreFreescaleARM®v7Boundary DevicesYes
ARM® Cortex®-A9 MPCore + Zync 7000 FPGAXilinxARM®v7Zed BoardYes
ARM® Cortex®-A9 MPCore + Zync 7000 FPGAXilinxARM®v7Digilent                 
Yes

ARM and Cortex are registered trademarks of ARM Limited (or its subsidiaries) in the EU and/or elsewhere. All rights reserved. ARM and TrustZone are registered trademarks of ARM Limited (or its subsidiaries) in the EU and/or elsewhere. All rights reserved. ARM and SecurCore are registered trademarks of ARM Limited (or its subsidiaries) in the EU and/or elsewhere. All rights reserved. Freescale, the Freescale logo, AltiVec, C-5, CodeTEST, CodeWarrior, ColdFire, ColdFire+, C-Ware, the Energy Efficient Solutions logo, Kinetis, MagniV, mobileGT, PEG, PowerQUICC, Processor Expert, QorIQ, QorIQ Qonverge, Qorivva, Ready Play, SafeAssure, the SafeAssure logo, StarCore, Symphony, VortiQa, Vybrid and Xtrinsic are trademarks of Freescale Semiconductor, Inc., Reg. U.S. Pat. & Tm. Off. iPhone is a trademark of Apple Inc., registered in the U.S. and other countries

Friday, November 21, 2014

C++ - Generative Programming


San Francisco Bay Area from Twin Peaks - Nikon D80



C++ IOStreams are a powerful mechanism for transforming input into output.  Most programmers are at least familiar with C++ IOStreams in the context of reading and writing bytes to a terminal or file.

When a file or terminal is opened for reading or writing by a process, the operating system returns a numerical identifier to the process.  This numerical identifier is known as a file descriptor.
In turn, the file or terminal can be written to by the process via this file descriptor.  The read and write system calls, which are implemented as wrappers in libc, are passed this numerical file descriptor.

Many layers of abstraction reside on top of the read and write system calls.  These layers of abstraction are implemented in both C and C++. Examples of C based layers of abstraction are fprintf and printf. Internally, these functions call the write system call.   An example of a C++ based layer of abstraction is the IOStreams hierarchy.  Out of the box, most C++ compiler toolchains provide an implementation of IOStreams.  IOStreams are an abstraction on top of the read and write system calls. When data is written to a terminal via an IOStream, the IOStream implementation calls the write system call.  Lastly, these layers of abstraction handle things such as buffering and file synchronization.

In UNIX, everything is a file. Consequently, network devices, virtual terminals, files, block devices, etc. can all be written to via a numerical file descriptor - this in turn is why UNIX is referred to as having a uniform descriptor space. With this being said, the basic IOStreams and printf abstractions I mentioned above are not designed to used with network sockets, pipes, and the sort.  The lower layer read and write system calls can be used but there are a number of functions that must be called before writing raw bytes to an open file descriptor that points to a network socket.

The additional functionality that is needed for communicating with network sockets, shared memory, and the like, can be implemented in classes that are derived from the C++ iostream class.  It is for this reason that the IOStreams classes are extended via inheritance.

Over the years, several popular C++ libraries have implemented classes that are derived from the base classes in the iostreams hierarchy.  The C++ Boost library is a popular example.  However; this has not always been the case.  Going back to 1999, the Boost library did not exist and there were one or two examples on the entire Internet as to how to properly extend the C++ IOStreams classes.  

In 1999, the source code for the GNU compiler toolchain that is available on gcc.gnu.org was obtained and a class hierarchy was derived to support sockets, pipes, and shared memory. The methods in the classes derived from the base classes in the iostreams library were designed to be reentrant and easy to use.  Generative programming techniques and template metaprogramming was used to create objects that could be instantiated using familiar C++ iostreams syntax and semantics. The library created was called mls and it was licensed under version 2 of the GPL

Since 1999, Boost has come a long way.  It provides support for cryptographic IOStreams, sockets, and all kinds of other fancy stuff. It uses generative programming techniques.

The gcc compiler toolchain can be obained from gcc.gnu.org.  Ctags can then be used to dig into the internals of the iostreams hierarchy.. The following book is recommended.

namespace mls 
{
template<class BufType, int direction, class BaseType=mlbuf> class mlstreamimpl;
template<class Parent, class BaseType=mlbuf> class mloutputimpl;
template<class Parent, class BaseType=mlbuf> class mlinputimpl;
template<class BufType, int direction, class BaseType=BufType>
struct StreamConfig;
template<class BufType, int direction, class BaseType>
struct StreamConfig
{
typedef typename SWITCH<(direction),
CASE<0,mlinputimpl<mlstreamimpl<BufType, direction, BaseType>, BufType>,
CASE<1,mloutputimpl<mlstreamimpl<BufType, direction, BaseType>, BufType>,
CASE<10,mlinputimpl<mloutputimpl<mlstreamimpl<BufType, direction, BaseType>,
BufType>, BufType >,
CASE<DEFAULT,mlinputimpl<mlstreamimpl<BufType, 10, BaseType>,
BufType > > > > > >::RET Base;
};
}