[3mdeb blog]

Thoughts dereferenced from scratchpad noise

FWTS on ARMv8 platform (HiKey LeMaker version) from scratch

| Comments

This is second post from series about LeMaker version of HiKey board from 96boards Customer Edition family. Previous post focused on describing hardware part. In this post I would like to show how to setup firmware development and testing environment.

This post highly rely on 96boards documentation, so kudos to 96boards and LeMaker for providing lot of information for developers.

Obtain pre-compiled binaries

1
2
3
4
5
6
7
wget https://builds.96boards.org/snapshots/hikey/linaro/uefi/latest/l-loader.bin
wget https://builds.96boards.org/snapshots/hikey/linaro/uefi/latest/fip.bin
wget https://builds.96boards.org/snapshots/hikey/linaro/uefi/latest/ptable-linux-8g.img
wget https://builds.96boards.org/snapshots/hikey/linaro/uefi/latest/nvme.img
wget https://builds.96boards.org/releases/hikey/linaro/debian/latest/boot-fat.uefi.img.gz
wget http://builds.96boards.org/snapshots/hikey/linaro/debian/latest/hikey-jessie_developer_20160225-410.emmc.img.gz
gunzip *.img.gz

Clone eMMC flashing tool:

1
git clone https://github.com/96boards/burn-boot.git

Follow flashing instructions. For Debian-based systems you may need:

1
sudo apt-get install python-serial android-tools-fastboot

On my Debian I see in dmesg:

1
2
3
4
5
6
7
8
[21174.122832] usb 3-2.2: USB disconnect, device number 15
[21343.166870] usb 3-2.1.1: new full-speed USB device number 17 using xhci_hcd
[21343.268348] usb 3-2.1.1: New USB device found, idVendor=12d1, idProduct=3609
[21343.268352] usb 3-2.1.1: New USB device strings: Mfr=1, Product=4, SerialNumber=0
[21343.268353] usb 3-2.1.1: Product: \xffffffe3\xffffff84\xffffffb0㌲㔴㜶㤸
[21343.268355] usb 3-2.1.1: Manufacturer: 䕇䕎䥎
[21343.269159] option 3-2.1.1:1.0: GSM modem (1-port) converter detected
[21343.269271] usb 3-2.1.1: GSM modem (1-port) converter now attached to ttyUSB2

Correct command and UART log should look similar to this:

1
2
3
4
5
6
7
8
9
[17:11:36] pietrushnic:images $ sudo python ../src/burn-boot/hisi-idt.py --img1=l-loader.bin -d /dev/ttyUSB2
+----------------------+
(' Serial: ', '/dev/ttyUSB2')
(' Image1: ', 'l-loader.bin')
(' Image2: ', '')
+----------------------+

('Sending', 'l-loader.bin', '...')
Done
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
usb reset intr
reset device done.
start enum.
enum done intr
Enum is starting.
usb reset intr
enum done intr
NULL package
NULL package
USB ENUM OK.
init ser device done....
USB:: Err!! Unknown USB setup packet!
NULL package
USB:: Err!! Unknown USB setup packet!
NULL package
USB:: Err!! Unknown USB setup packet!
NULL package
USB:: Err!! Unknown USB setup packet!
NULL package
uFileAddress=ss=f9800800
uFileAddress=ss=f9800800

Switch to aarch64 mode. CPU0 executes at 0xf9801000!

As result I saw that green LED on board is on, then I proceed with fastboot commands.

If above steps finish without the problems, then you know working procedure for flashing all required components. Now let’s proceed with fast boot and flashing remaining components:

1
2
3
4
5
sudo fastboot flash ptable ptable-linux-8g.img
sudo fastboot flash fastboot fip.bin
sudo fastboot flash nvme nvme.img
sudo fastboot flash boot boot-fat.uefi.img
sudo fastboot flash system hikey-jessie_developer_20160225-410.emmc.img

Output should look like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
$ sudo fastboot flash ptable ptable-linux-8g.img 
target reported max download size of 268435456 bytes
sending 'ptable' (17 KB)...
OKAY [  0.001s]
writing 'ptable'...
OKAY [  0.004s]
finished. total time: 0.006s
$ sudo fastboot flash fastboot fip.bin
target reported max download size of 268435456 bytes
sending 'fastboot' (1383 KB)...
OKAY [  0.060s]
writing 'fastboot'...
OKAY [  0.135s]
finished. total time: 0.196s
$ sudo fastboot flash nvme nvme.img
target reported max download size of 268435456 bytes
sending 'nvme' (128 KB)...
OKAY [  0.006s]
writing 'nvme'...
OKAY [  0.007s]
finished. total time: 0.014s
$ sudo fastboot flash boot boot-fat.uefi.img
target reported max download size of 268435456 bytes
sending 'boot' (65536 KB)...
OKAY [  2.645s]
writing 'boot'...
OKAY [  3.258s]
finished. total time: 5.903s
$ sudo fastboot flash system hikey-jessie_developer_20160225-410.emmc.img
target reported max download size of 268435456 bytes
sending sparse 'system' (262140 KB)...
OKAY [ 10.692s]
writing 'system'...
OKAY [ 11.868s]
sending sparse 'system' (262140 KB)...
OKAY [ 10.786s]
writing 'system'...
OKAY [ 11.838s]
sending sparse 'system' (262140 KB)...
OKAY [ 10.791s]
writing 'system'...
OKAY [ 11.812s]
sending sparse 'system' (262140 KB)...
OKAY [ 10.720s]
writing 'system'...
OKAY [ 11.803s]
sending sparse 'system' (262140 KB)...
OKAY [ 10.833s]
writing 'system'...
OKAY [ 11.830s]
sending sparse 'system' (116064 KB)...
OKAY [  4.854s]
writing 'system'...
OKAY [  5.219s]
finished. total time: 123.047s

Remove Boot Select jumper (link 3-4) and power on platform.

System configuration

Wireless network can be easily configured using this instructions. It is also required to setup DNS in /etc/resolv.conf ie.:

1
nameserver 8.8.8.8

Bug hunting

There was time when I asked myself what I can do ? Where to start ? Good way to analyze system compatibility (and find bugs) from firmware perspective is FirmwareTestSuit. It can be cloned using:

1
git clone git://kernel.ubuntu.com/hwe/fwts.git

To compile:

1
2
3
4
5
apt-get update
apt-get install autoconf automake libglib2.0-dev libtool libpcre3-dev libjson0-dev flex bison dkms
autoreconf -ivf
./configure
make -j$(nproc)

To run:

1
./src/fwts

At point of writing this post only 13 tests passed. Most of testes (243) were aborted since no support for given feature was detected. This results show that there is plenty to do before getting well-supported firmware on HiKey.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
Test           |Pass |Fail |Abort|Warn |Skip |Info |
---------------+-----+-----+-----+-----+-----+-----+
acpiinfo       |     |     |     |     |     |    2|
acpitables     |     |     |    1|     |     |     |
asf            |     |     |    1|     |     |     |
aspm           |     |     |     |     |    1|     |
aspt           |     |     |    1|     |     |     |
bert           |     |     |    1|     |     |     |
bgrt           |     |     |    1|     |     |     |
bmc_info       |     |     |     |     |    1|     |
boot           |     |     |    1|     |     |     |
checksum       |     |     |     |     |     |     |
cpep           |     |     |    1|     |     |     |
cpufreq        |    5|     |     |     |    2|     |
csrt           |     |     |    1|     |     |     |
dbg2           |     |     |    1|     |     |     |
dbgp           |     |     |    1|     |     |     |
dmicheck       |     |    1|     |     |    2|     |
drtm           |     |     |    1|     |     |     |
ecdt           |     |     |    1|     |     |     |
einj           |     |     |    1|     |     |     |
erst           |     |     |    1|     |     |     |
facs           |     |     |    1|     |     |     |
fadt           |     |     |    6|     |     |     |
fpdt           |     |     |    1|     |     |     |
gtdt           |     |     |    1|     |     |     |
hest           |     |     |    1|     |     |     |
iort           |     |     |    1|     |     |     |
klog           |     |     |     |     |     |     |
lpit           |     |     |    1|     |     |     |
madt           |     |     |    5|     |     |     |
maxreadreq     |    1|     |     |     |     |     |
mchi           |     |     |    1|     |     |     |
method         |     |     |  192|     |     |     |
mpst           |     |     |    1|     |     |     |
msct           |     |     |    1|     |     |     |
msdm           |     |     |    1|     |     |     |
mtd_info       |     |     |     |     |    1|     |
nfit           |     |     |    1|     |     |     |
olog           |     |     |     |     |    1|     |
oops           |    2|     |     |     |     |     |
pcct           |     |     |    1|     |     |     |
pmtt           |     |     |    1|     |     |     |
prd_info       |     |     |     |     |    1|     |
rsdp           |     |     |    1|     |     |     |
rsdt           |     |     |    1|     |     |     |
sbst           |     |     |    1|     |     |     |
securebootcert |     |     |    1|     |     |     |
slic           |     |     |    1|     |     |     |
slit           |     |     |    1|     |     |     |
spcr           |     |     |    1|     |     |     |
spmi           |     |     |    1|     |     |     |
srat           |     |     |    1|     |     |     |
stao           |     |     |    1|     |     |     |
syntaxcheck    |     |     |     |     |     |     |
tcpa           |     |     |    1|     |     |     |
tpm2           |     |     |    1|     |     |     |
uefi           |     |     |    1|     |     |     |
uefibootpath   |     |     |     |     |    1|     |
version        |     |     |     |     |    1|    3|
waet           |     |     |    1|     |     |     |
wakealarm      |    5|    1|     |     |     |     |
wdat           |     |     |    1|     |     |     |
wpbt           |     |     |    1|     |     |     |
xenv           |     |     |    1|     |     |     |
xsdt           |     |     |    1|     |     |     |
---------------+-----+-----+-----+-----+-----+-----+
Total:         |   13|    2|  248|    0|   11|    5|
---------------+-----+-----+-----+-----+-----+-----+

Summary

As presented above HiKey developement process is not so simple. Using precompiled binaries is very useful for presentation purposes, but adding features to EDK2 will requires recompilation some of mentioned components. Documentation is not easy to search as well as forum, key probablem is that it needs more order, because various information (sometimes unrelated) are spread actoss directories and repositories.

Nevertheless hacking ARMv8 firmware may be fun and there huge undiscovered area to explore. Key question is what valid use cases may lead to extensive firmware development in this area ? First I would look into features that have to be exposed to operating system ie. verify boot for Linux OS use of TEE module in Linux.

As always please share if you feel this is valuable and comment if you have any questions or something is unclear.

Directory scheme for multiple projects

| Comments

How to keep clean organization while working on multiple projects ?

Answer to this question depends on workflow and nature of projects itself.

Below I would like to present my approach to manage sanity while having multiple projects going simultaneously. This would be Embedded Systems Consultant view and will mostly show directory organization, but I think it can be adopted to other programmers workflow.

Directory organization

Usually I have up to 10 projects from external customer running and ~3 internal. Obviously better organization minimize overhead related to searching and wondering where to put recently obtained file. During last 3 years I collected over 60 projects for 45 customers.

Based on that experience I created directory structure that work pretty good for above numbers. Scheme looks like this:

1
${HOME}/projects/<year>/<customer>/<project-name>/{logs,images,releases,src}

Customer/year order

One flaw that this setup has is for project that last more then year. I don’t think making it <customer>/<year> improve things, because then I would have tens of even hundred of directories in projects. Splitting it by year makes searching focused. For now, when I deal with project longer then year I just copy relevant part from previous year. By relevant part I mean something that I really have to use, not one time reference. This can be for example particular SD card image that is still used as development base.

Customer

Customer part is trivial, although sometimes can cause confusion. There are situation where I start research not knowing what company I work for, because I was reached not from company domain. There are also cases when someone reach me over freelance portals (Upwork, Guru etc.) that information provided are outdated or simply invalid.

Having correct customer name is important only at invoicing stage, before that if I’m not clear I just place some made up string that can uniquely identify customer. Usually this is company name and contact person name, if company unknown.

Project name

Usually prototype projects doesn’t have marketing name, but project can be called by SoC/CPU/dev board + main feature ie. a20_camera, bbb_canbus_reader etc.

What most embedded projects needs ?

After couple years I found that couple thing are typically needed:

  • logs – this directory is used most of the times, I tend to run minicom in it with enabled logging, you never know when you will need information form this directory, naming convention for log files is something I still struggle

  • images – this is directory for OS images, typically I have here SD card images and ISO images of distros used in project, sometimes you may end up keeping multiple instance of the same OS in various projects, but with 1TB disc this should not be big concern, you can always search for duplicates, knowing where your OS is and avoiding downloading it again can save some time

  • releases – this directory contain all releases, developers usually use work in progress code, but customer receive release version of deliverables and usually will report bugs against particular release version

  • src – this directory keep all source code related to project, those are mostly git repositories cloned inside directory

Sample directory structure may look like that:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
.
└── projects
    ├── 2015
    │   └── acme1
    │       ├── foo1
    │       │   ├── images
    │       │   ├── logs
    │       │   ├── releases
    │       │   └── src
    │       └── foo2
    │           ├── images
    │           ├── logs
    │           ├── releases
    │           └── src
    └── 2016
        └── acme2
            ├── foo1
            │   ├── images
            │   ├── logs
            │   ├── releases
            │   └── src
            └── foo2
                ├── images
                ├── logs
                ├── releases
                └── src

Summary

I hope this concept is somehow useful for you. I want to keep above information for self reference, because I was asked couple times how to organize multiple projects. Explaining this each time leads to this article. Of course whole organization is very subjective and may not work good for everyone.

Powering on LeMaker HiKey (ARMv8)

| Comments

Embedded Systems Consultants have chance to live in interesting times. ARM expansion touch server market and UEFI coming to non-x86 platforms. Firmware gaining its importance and because handling real development is harder and harder lot of things starting to happen in open source. Big players trying to address security and virtualization issues, what leads to really interesting features in recent SoCs.

Couple weeks ago I decided to recover my knowledge about UEFI and take a look how it is implemented for architecture that have its momentum – namely ARM in its 8 version (ARMv8). Short review of technology reveal universe that should be studied by every aspiring Embedded Systems adept.

Choosing ARMv8 dev board

First problem was to choose development board. Probably simpler solution is to use platforms like Raspberry Pi 3 which features Broadcom Cortex-A53 or very interesting alternative like PINE64 with Allwinner flavour.

Of course rush on this market bring other players like Amlogic with Odroic-C2. It is worth to mention that adaptation of new architecture is very slow. It was announced in 2012. First real product was released by Apple (iPhone S5), but despite various commercial products, since 2012 not much appeared on low end development board market, which is probably main area for makers and prototyping shops. Things start to change last year.

I have RPi3 on my desk but playing with its low level side is not encouraging because of limitation Broadcom put on releasing any information about BCM2837. My goal was to work on UEFI and ARM trusted firmware the only board except expensive ARM reference platforms that seems to work with UEFI was LeMaker HiKey.

Why 96boards ?

  • this is open specification – IIRC this is first of its kind and it is high chance to be widely accepted
  • its driven by Linaro, which in my opinion do a lot of great work for whole community
  • its standardized way with big players behind, so knowing it and having in portfolio cannot damage Embedded Systems Consultant career
  • IMO this approach in long term will have better return on investment, then custom quick shots made by not-so-community-friendly vendors

Power supply

Expected power input is 8-18V. I understand the need for higher and wider voltage range, but this is for sure not standard in makers/hackers community. I have ton of 5V/2A power supplies in stock, also for 5V I can use my active USB hub or even PC port for not power hungry devices.

Reasoning behind this choice can be found here.

Finally to not add more USD to my ARMv8 development environment I used my Zhaoxin DC power supply and unused plug from universal power supply.

1.8V UART

My second surprise was that board use 1.8V level for UART. Cables for that level are built with FT230XS or similar chips, which cost ~3USD. To my suprise cable that work with 1.8V UART level cost 30USD. There are 2 separated UART pins to connect on HiKey. One for low level bootloader development and one for Linux kernel development. So I would need to cables. Board cost 75USD, so you paying almost the same price for cables. It was not acceptable for me.

Linaro developers seems to use this which is out of stock for 5 months!

While searching for alternatives I found this TI converter on SparkFun page. Luckily availability of various SparkFun distributors made delivery possible in less then 48h.

After wiring up with TXB0104 everything seems to work ok.

Note that board use 2 UARTs. UART0 for bootloader development. This is connector with not typical pitch (2.0mm) and UART3 as debug port for Linux kernel output.

The only problem with wiring is that using one TI chip you can only have one reference Vcc for USB to serial UART, so you have to select one of them as reference and assume that second will have very similar level without much noise. I understand this is electronically probably not perfect, but I moved forward with that budget solution.

Booting OS

Board is pre-installed with Debian, so +1 for choice. It boots smooth and you can also see bootloader logs.

On top there is bootloader on bottom booted Debian. Bootloader logs came from OP-TEE Trusted OS,

Summary

Setting up hardware to boot and having some debug output is initial step to start development. Once this point is passed I can start to deal with UEFI and(or) ARM Trusted Firmware (ATF). It is important to note that documentation on GitHub and in Hardware User Manual is very good and huge kudos should go to Linaro people for putting so much effort into that.

Things that I would like to write about in future posts:

  • UEFI setup for HiKey
  • UEFI capabilities and limitation
  • ATF development

As always please share if you think content maybe valuable to other.

PC Engines APU2 netboot Debian installation

| Comments

In previous post I described how to setup PXE server and boot Debian installer using it. I mentioned that provided setup is limited and some extensive configuration is needed to make it useful for real world example. Since that time I learned that there is chain command in iPXE, which give ability to use arbitrary TFTP server as boot file source.

Using RPi PXE server

For example by changing my test network topology from previous post to something like that:

In short Raspberry Pi contain our PXE server configured in previous post. TL-MR3420 is our DHCP server and PC Engines APU2A4 is our target box where we want to install Debian.

We need to change eth0 configuration, so our PXE server will get IP automatically from DHCP:

1
2
auto eth0
iface eth0 inet dhcp

Also disable udhcpd:

1
sudo update-rc.d udhcpd disable

Then reboot PXE server.

PXE booting

First enter iPXE on APU2 board by pressing <Ctrl-B> during boot. You should see something like that:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
iPXE (http://ipxe.org) 00:00.0 C100 PCI2.10 PnP PMMpmm call arg1=1
pmm call arg1=0
+DFF490B0pmm call arg1=1
pmm call arg1=0
+DFE890B0 C100


iPXE (PCI 00:00.0) starting execution...ok
iPXE initialising devices...ok



iPXE 1.0.0+ (e303) -- Open Source Network Boot Firmware -- http://ipxe.org
Features: DNS FTP HTTP HTTPS iSCSI NFS SLAM TFTP VLAN AoE ELF MBOOT NBI PXE SDI bzImage COMBOOT Menu PXEXT
iPXE>

Then obtain DHCP address:

1
2
iPXE> dhcp net0
Configuring (net0 00:0d:b9:3f:9e:58)............... ok

Now we can boot over the network using RPi PXE server:

1
2
3
iPXE> set filename /srv/tftp/pxelinux.0
iPXE> set next-server 192.168.0.100
iPXE> chain tftp://${next-server}/${filename}

Note that 192.168.0.100 is RPi PXE server and /srv/tftp/pxelinux.0 is path on RPi exposed through TFTP configuration.

Debian installer modification

Hit Tab in the main installer window:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
             +---------------------------------------+
             | Debian GNU/Linux installer boot menu |
             |---------------------------------------|
             | Install                               |
             | Advanced options                    > |
             | Help                                  |
             | Install with speech synthesis         |
             |                                       |
             |                                       |
             |                                       |
             |                                       |
             |                                       |
             |                                       |
             +---------------------------------------+



          Press ENTER to boot or TAB to edit a menu entry

Change boot command line to print output to serial:

1
> debian-installer/i386/linux vga=788 initrd=debian-installer/i386/initrd.gz --- console=ttyS0,115200 earlyprint=serial,ttyS0,115200

Then hit Enter. You will see complains about video mode like this:

1
Press <ENTER> to see video modes available, <SPACE> to continue, or wait 30 sec

Follow this instruction by waiting or hitting Space. Then you should have running installer.

Debian installation

This is typical installation except it happen over serial. As a storage I used 16GB USB stick with guided partitioning. At the end I also installed GRUB on USB stick MBR.

Be patient if serial console will be blank for some time it happen when installing over network.

After reboot you should be able to choose USB stick from boot menu (F10) and your Debian on APU2 should be ready:

1
2
3
4
5
6
7
8
9
10
11
12
13
Debian GNU/Linux 8 Maedhros ttyS0

Maedhros login: pietrushnic
Password: 
Linux Maedhros 3.16.0-4-686-pae #1 SMP Debian 3.16.7-ckt20-1+deb8u4 (2016-02-29) i686

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
pietrushnic@Maedhros:~$ 

Summary

Now when you have Debian installed on your system you can think about various improvements. For example:

  • Xen installation
  • Putting together automated installation using PXE server
  • Setup NFS and TFTP for Linux kernel development and testing

I hope this post was useful. If you think that it can be improved please comment. Thanks for reading.

PXE server with Raspberry Pi 1

| Comments

Recent days we get the announcement about releasing Raspberry Pi 3. Those of you who play with embedded systems or just try to make things probably still got good old Raspberry Pi (1). Because during time old platforms loose value as potential candidate for new projects I decided to sacrifice my old RPi and make test server from it.

One of my customer required testing his software against PXE server with various configurations. I realized that using my home network with my TP-Link router I have no way to create such configuration on server machine I usually use. I would need to connect directly to server and with one Ethernet port this was not the solution for me. My other platforms like A20 boards, Odroid or RPi2 are occupied by some projects. I recall that I have old RPi that can be used for that purpose.

Configuration described below is very limited because it test just PXE booting, there is no outside world connection. This connection can be added by adding wifi dongle to Raspberry Pi and modifying iptables and routing.

Prerequisites

  • download recent Raspberry Pi image and flash it to SD card. I used Raspbian Jessie Lite.
  • if you don’t have free keyboard and HDMI monitor use UART to connect serial console – you can use this post, if you don’t konw how to connect it
  • flash recent iPXE to your hardware or use what is already provided by vendor

Raspbian Jessie Lite – initial setup

Setup TFTP

Install server TFTP:

1
sudo apt-get install tftpd-hpa

Change configuration according to your needs. My looks like that:

1
2
3
4
5
6
7
# /etc/default/tftpd-hpa

TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS="0.0.0.0:69"
#TFTP_OPTIONS="--secure"
TFTP_OPTIONS=""

Download netboot files for Debian, which we will use for testing purposes:

1
wget http://ftp.nl.debian.org/debian/dists/jessie/main/installer-i386/current/images/netboot/netboot.tar.gz

Unpack netboot package in /srv/tftp:

1
2
cd /srv/tftp
sudo tar xvf /path/to/netboot.tar.gz

Setup udhcpd

Install udhcpd and remove conflicting packages:

1
2
sudo apt-get install udhcpd
sudo apt-get remove isc-dhcp-client 

At the end of /etc/udhcpd.conf add:

1
2
3
4
5
6
7
8
9
siaddr          192.168.0.1
boot_file       /srv/tftp/pxelinux.0
opt     dns     192.168.0.1 192.168.10.10
option  subnet  255.255.255.0
opt     router  192.168.0.1
opt     wins    192.168.0.1
option  dns     129.219.13.81
option  domain  local
option  lease   864000

You can also assign client MAC to given IP address by adding:

1
2
#static_lease 00:60:08:11:CE:4E 192.168.0.54
static_lease <mac> <ip>

Comment DHCPD_ENABLE in /etc/default/udhcpd:

1
2
3
4
5
6
7
8
9
# Comment the following line to enable
# DHCPD_ENABLED="no"

# Options to pass to busybox' udhcpd.
#
# -S    Log to syslog
# -f    run in foreground

DHCPD_OPTS="-S"

Change eth0 configuration to static IP:

1
2
3
4
5
auto eth0
iface eth0 inet static
        address 192.168.0.1
        netmask 255.255.255.0
        gateway 192.168.0.254

Then reboot device and connect your PXE client device.

Testing PXE server

When device boot press Ctrl-B to enter iPXE shell. If you cannot enter shell please replace iPXE with recent version using this instructions.

Entering iPXE you should see something like that:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
iPXE (http://ipxe.org) 00:00.0 C100 PCI2.10 PnP PMMpmm call arg1=1
pmm call arg1=0
+DFF490B0pmm call arg1=1
pmm call arg1=0
+DFE890B0 C100


iPXE (PCI 00:00.0) starting execution...ok
iPXE initialising devices...ok



iPXE 1.0.0+ (e303) -- Open Source Network Boot Firmware -- http://ipxe.org
Features: DNS FTP HTTP HTTPS iSCSI NFS SLAM TFTP VLAN AoE ELF MBOOT NBI PXE SDI bzImage COMBOOT Menu PXEXT
iPXE>  

First let’s configure interface:

1
2
3
4
iPXE> ifconf net0
Configuring (net0 00:0d:b9:3f:9e:58)............... ok
iPXE> dhcp net0
Configuring (net0 00:0d:b9:3f:9e:58)............... ok

And boot Debian installer:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
iPXE> autoboot
net0: 00:0d:b9:3f:9e:58 using i210-2 on PCI01:00.0 (open)
  [Link:up, TX:20 TXE:0 RX:8 RXE:2]
  [RXE: 2 x "The socket is not connected (http://ipxe.org/380f6001)"]
Configuring (net0 00:0d:b9:3f:9e:58)............... ok
net0: 192.168.0.194/255.255.255.0 gw 192.168.10.2
net0: fe80::20d:b9ff:fe3f:9e58/64
net1: fe80::20d:b9ff:fe3f:9e59/64 (inaccessible)
net2: fe80::20d:b9ff:fe3f:9e5a/64 (inaccessible)
Next server: 192.168.0.1
Filename: /srv/tftp/pxelinux.0
tftp://192.168.0.1//srv/tftp/pxelinux.0... ok
pxelinux.0 : 42988 bytes [PXE-NBP]
PXELINUX 6.03 PXE 20150819 Copyright (C) 1994-2014 H. Peter Anvin et al+---------------------------------------+
| ^GDebian GNU/Linux installer boot menu |
|---------------------------------------|
| Install                               |
| Advanced options                    > |
| Help                                  |
| Install with speech synthesis         |
|                                       |
|                                       |
|                                       |
|                                       |
|                                       |
|                                       |
+---------------------------------------+Press ENTER to boot or TAB to edit a menu entry     

Summary

It took me some time to put this information together an correctly run this server, so for future reference and for those confused with udhcpd and other tools configuration this post should be useful. Thanks for reading and as always please share if you think this post is valuable. If anything is not clear or I messed something please let me know in comments.

Netcat - how to transfer files without scp or ftp

| Comments

One of my recent customers provided me hardware with custom Linux system. Distribution used on this hardware was very limited there was no developers tools, file transfer applications (like scp, ftp or even tftp) or communication clients like ssh. I had to deploy some firmware files to the system without modifying it. This was i386 machine. Of course I could compile something and add this software using usb stick or other stoarge, but what if I would not have direct access to hardware ? Also for development and testing purposes it would be much easier to use network transfer, then running with usb stick.

When looking for answer I found this. I heard before about netcat, but more in context of debugging then using it as file transfer application. Luckily nc as very small tool is in almost all distributions and it was also available in my small custom distro.

File transfer with netcat

nc by man page is described as TCP/IP swiss army knife , but can be used to transfer files.

What have to be done is setting receiving side ie.:

1
nc -l -p 2020 > my_file.bin

What tell nc to listen on inbound connection (-l) on port 2020 (-p 2020) and redirect content of incoming packages to my_file.bin.

On sender side we pipe my_file.bin to nc like that:

1
cat my_file.bin | nc <dest_ip_addr> 2020

Which cause nc to create TCP connection to <dest_ip_addr> on port 2020 and send everything it gets on standard input.

Known flaws

From what I saw sometimes nc doesn’t end at EOF and just hang waiting for next data, which never come. In that case I just break with Ctrl-C on both ends. Then check if all stuff was transfered correctly by verifying MD5 sum on sender and receiver side. In most cases files pass this integrity test.

Emulate Rapberry Pi 2 in QEMU

| Comments

In the process of planning system testing for one of my clients I found that someone from Microsoft published patches with BCM2836 support to QEMU mailing list. I thought it is very interesting, because if it is possible to setup emulated Raspberry Pi many use cases can be tested faster and in more automatic way. For example checking how application behave when running on more then one device at once, testing massive deployment process, stress testing and finally speed up debug-fix-test process.

So it looks like making RPi 2 working in emulated environment can add a lot of value to some products. In email Andrew mention github repo, which I would like to try in this post

Get QEMU and compile

1
2
3
4
5
git clone https://github.com/0xabu/qemu.git -b raspi
git submodule update --init dtc
./configure
make -j$(nproc)
sudo make install

Prepare to boot

QEMU requires kernel and device tree file to be given as parameters, because of that we have to extract those pieces from existing Raspbian image.

Get kernel and device tree

1
2
3
4
5
6
7
8
9
10
11
12
13
wget http://downloads.raspberrypi.org/raspbian/images/raspbian-2015-11-24/2015-11-21-raspbian-jessie.zip
unzip 2015-11-21-raspbian-jessie.zip
[23:35:23] pietrushnic:rpi2_qemu $ sudo /sbin/fdisk -lu 2015-11-21-raspbian-jessie.img 
Disk 2015-11-21-raspbian-jessie.img: 3.7 GiB, 3934257152 bytes, 7684096 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xea0e7380

Device                          Boot  Start     End Sectors  Size Id Type
2015-11-21-raspbian-jessie.img1        8192  131071  122880   60M  c W95 FAT32 (LBA)
2015-11-21-raspbian-jessie.img2      131072 7684095 7553024  3.6G 83 Linux

Check start of W95 FAT32 (LBA) partition. It is 8192. Sector size is 512. So calculate offset in bytes 8192 * 512 = 4194304.

1
2
3
4
5
mkdir tmp
sudo mount -o loop,offset=4194304 2015-11-21-raspbian-jessie.img tmp
mkdir 2015-11-21-raspbian-boot
cp tmp/kernel7.img 2015-11-21-raspbian-boot
cp tmp/bcm2709-rpi-2-b.dtb 2015-11-21-raspbian-boot

Then if you try to boot 2015-11-21 Rapbian with 0xabu code:

1
2
3
4
qemu-system-arm -M raspi2 -kernel 2015-11-21-raspbian-boot/kernel7.img \
-sd 2015-11-21-raspbian-jessie.img \
-append "rw earlyprintk loglevel=8 console=ttyAMA0,115200 dwc_otg.lpm_enable=0 root=/dev/mmcblk0p2" \
-dtb 2015-11-21-raspbian-boot/bcm2709-rpi-2-b.dtb -serial stdio

You will experience kernel crash:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
(...)
[    6.021989] Freeing unused kernel memory: 420K (80779000 - 807e2000)
[    7.366232] random: systemd urandom read with 7 bits of entropy available
[    7.383057] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000004
[    7.383057] 
[    7.384366] CPU: 0 PID: 1 Comm: systemd Not tainted 4.1.13-v7+ #826
[    7.384874] Hardware name: BCM2709
[    7.386615] [<80018444>] (unwind_backtrace) from [<80013e08>] (show_stack+0x20/0x24)
[    7.387307] [<80013e08>] (show_stack) from [<8055a188>] (dump_stack+0x98/0xe0)
[    7.387851] [<8055a188>] (dump_stack) from [<80556340>] (panic+0xa4/0x204)
[    7.388515] [<80556340>] (panic) from [<800293c8>] (do_exit+0xa0c/0xa64)
[    7.389074] [<800293c8>] (do_exit) from [<800294b8>] (do_group_exit+0x4c/0xcc)
[    7.389729] [<800294b8>] (do_group_exit) from [<80033f1c>] (get_signal+0x2b0/0x6e0)
[    7.390388] [<80033f1c>] (get_signal) from [<80013190>] (do_signal+0x98/0x3ac)
[    7.391021] [<80013190>] (do_signal) from [<8001368c>] (do_work_pending+0xb8/0xc8)
[    7.391665] [<8001368c>] (do_work_pending) from [<8000f9e4>] (work_pending+0xc/0x20)
[    7.393209] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000004
[    7.393209] 

To avoid this crash you have to comment /etc/ld.so.preload.

Changing ld.so.preload

First calculate offset in bytes to Raspbian root filesystem partition. According to fdisk output above partition starts with sector 131072, so offset would be 512*131072=67108864.

1
sudo mount -o loop,offset=67108864 2015-11-21-raspbian-jessie.img tmp

Use your favourite editor to change tmp/etc/ld.so.preload. Note that you have to edit as superuser. Content of file should looks like this:

1
#/usr/lib/arm-linux-gnueabihf/libarmmem.so

Sync and umount partition:

1
2
sync
sudo umount tmp

Final booting

1
2
3
4
qemu-system-arm -M raspi2 -kernel 2015-11-21-raspbian-boot/kernel7.img \
-sd 2015-11-21-raspbian-jessie.img \
-append "rw earlyprintk loglevel=8 console=ttyAMA0,115200 dwc_otg.lpm_enable=0 root=/dev/mmcblk0p2" \
-dtb 2015-11-21-raspbian-boot/bcm2709-rpi-2-b.dtb -serial stdio

Summary

There are many problem with existing setup, but from my experience this is best approach and code that I saw during last years. Also it looks like this code is backed by huge corporation so it looks like they see value in providing this code to wide community. Rapid delivery of those patches probably would not be possible without previous work to which Andrew point in his email. It would be great to see community engagement in this effort.

Using PlatformIO with TI MSP430 LunchPads

| Comments

PlatformIO is very interesting project that aim to solve very important problem of configuring deployment environment for embedded systems. IMHO good approach is to focus on modularity (various IDE can be used, even Vim) and simplicity (in best case 2 command should be enough to deploy first code).

Recent years we have explosion of bootstraping applications (ie.vagrant, puppet). Most of them seems to follow git-like command line interface and getting a lot of attention from programmers community. PlatformIO is promising project for all Embedded Software developers who in the era of IoT came from Linux systems.

It take some time to try PlatformIO using real hardware. Luckily on my desk there are 2 supported boards gathering dust, which I would like to try in this post.

MSP-EXP430F5529LP on the left and MSP-EXP430FR5969 on the right.

Installation on Debian

I highly recommend using virtualenv for any custom python application.

At the beginning I simply follow Getting Started page.

1
2
pip install -U pip setuptools
pip install -U platformio

What configuration I should use for my boards ?

1
2
3
4
5
[13:38:34] pietrushnic:msp430 $ platformio boards|grep 5969
lpmsp430fr5969        msp430fr5969   8Mhz      64Kb    1Kb    TI LaunchPad w/ msp430fr5969
[13:38:41] pietrushnic:msp430 $ platformio boards|grep 5529
lpmsp430f5529         msp430f5529    16Mhz     128Kb   1Kb    TI LaunchPad w/ msp430f5529 (16MHz)
lpmsp430f5529_25      msp430f5529    25Mhz     128Kb   1Kb    TI LaunchPad w/ msp430f5529 (25MHz)

So it looks like 5529 have 2 flavours. According to Energia 16MHz option is for backward compatibility. Let’s use recent 25MHz config.

1
2
3
mkdir msp430
cd msp430
platformio init --board=lpmsp430fr5969 --board=lpmsp430f5529_25

PlatformIO first ask if we want auto-uploading successfully built project, so I answered y. Then inform about creating some directories and platformio.ini file. After confirming toolchain, downloading starts.

Problems with MSP430F5529LP

Lack of main.cpp

If you run PlatformIO without any source code in src directory you will get error message like this:

1
2
3
4
5
.pioenvs/lpmsp430f5529_25/libFrameworkEnergia.a(main.o): In function `main':
/home/pietrushnic/projects/3mdeb/msp430/.pioenvs/lpmsp430f5529_25/FrameworkEnergia/main.cpp:7: undefined reference to `setup'
/home/pietrushnic/projects/3mdeb/msp430/.pioenvs/lpmsp430f5529_25/FrameworkEnergia/main.cpp:10: undefined reference to `loop'
collect2: ld returned 1 exit status
scons: *** [.pioenvs/lpmsp430f5529_25/firmware.elf] Error 1

Of course adding main.cpp to src directory fix this issue. As sample code you may use MSP430F55xx_1.c

libmsp430.so: cannot open shared object file

Next problem is with libmsp430.so which is not visible by mspdebug, but was installed by PlatformIO in $HOME/.platformio/packages/toolchain-timsp430/bin/libmsp430.so.

Running:

1
export LD_LIBRARY_PATH=$HOME/.platformio/packages/toolchain-timsp430/bin/

before calling platformio fix problem. For some users even better would be to make libmsp430.so accessible system wide:

1
sudo cp $HOME/.platformio/packages/toolchain-timsp430/bin/libmsp430.so /usr/lib

tilib: device initialization failed

If you didn’t use your MSP430 for a while there can be problem like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$HOME/.platformio/packages/tool-mspdebug/mspdebug tilib --force-reset "prog .pioenvs/lpmsp430f5529_25/firmware.hex"
MSPDebug version 0.20 - debugging tool for MSP430 MCUs
Copyright (C) 2009-2012 Daniel Beer <dlbeer@gmail.com>
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

MSP430_GetNumberOfUsbIfs
MSP430_GetNameOfUsbIf
Found FET: ttyACM0
MSP430_Initialize: ttyACM0
FET firmware update is required.
Re-run with --allow-fw-update to perform a firmware update.
tilib: device initialization failed
scons: *** [upload] Error 255

Fix for that according to error log should be like this:

1
$HOME/.platformio/packages/tool-mspdebug/mspdebug tilib --allow-fw-update

But this can cause additional problems that I reported here. I finally managed to fix problem using hints from Agla Blog.

Because gcc-msp430 was removed from Debian Sid we have to use compiler delivered by platformio to test blinky example from Agla blog:

1
$HOME/.platformio/packages/toolchain-timsp430/bin/msp430-gcc -mmcu=msp430f5529 -mdisable-watchdog blink.c

Problems with MSP430FR5969

I experienced very similar problems with FR5969. Unfortunately above procedure led me to:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
MSPDebug version 0.23 - debugging tool for MSP430 MCUs
Copyright (C) 2009-2015 Daniel Beer <dlbeer@gmail.com>
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Chip info database from MSP430.dll v3.3.1.4 Copyright (C) 2013 TI, Inc.

Using old API
MSP430_GetNumberOfUsbIfs
MSP430_GetNameOfUsbIf
Found FET: ttyACM0
MSP430_Initialize: ttyACM0
Firmware version is 30301004
MSP430_VCC: 3000 mV
MSP430_OpenDevice
tilib: MSP430_OpenDevice: Unknown device (error = 5)
tilib: device initialization failed

Building libmsp430.so

This probably means that default libmsp430.so, downloaded probably from Energia project, doesn’t support FR5969. So I tried build libmsp430.so by myself:

1
2
3
4
5
6
7
8
9
10
11
12
sudo apt-get install libboost-system-dev libboost-filesystem-dev
git clone https://github.com/pietrushnic/MSPDebugStack_OS_Package.git -b libmsp430-fr5969
git clone https://github.com/signal11/hidapi.git
cd hidapi
./bootstrap
./configure --with-pic
make
cp ./libusb/hid.o ../MSPDebugStack_OS_Package/ThirdParty/lib64
cp ./hidapi/hidapi.h ../MSPDebugStack_OS_Package/ThirdParty/include
cd ../MSPDebugStack_OS_Package
make
sudo cp libmsp430.so /usr/lib

This improved situation, but give:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
MSPDebug version 0.23 - debugging tool for MSP430 MCUs
Copyright (C) 2009-2015 Daniel Beer <dlbeer@gmail.com>
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Chip info database from MSP430.dll v3.3.1.4 Copyright (C) 2013 TI, Inc.

Using new (SLAC460L+) API
MSP430_GetNumberOfUsbIfs
MSP430_GetNameOfUsbIf
Found FET: ttyACM0
MSP430_Initialize: ttyACM0
FET firmware update is required.
Starting firmware update (this may take some time)...
Initializing bootloader...
Programming new firmware...
    75 percent done
    84 percent done
    84 percent done
    91 percent done
    96 percent done
    99 percent done
   100 percent done
   100 percent done
Initializing bootloader...
Programming new firmware...
     4 percent done
    20 percent done
    36 percent done
    52 percent done
    68 percent done
    84 percent done
   100 percent done
Update complete
Done, finishing...
tilib: MSP430_FET_FwUpdate: MSP-FET / eZ-FET legacy module update failed (error = 75)
tilib: device initialization failed

I’m not sure why this message appear, but when tried 2nd time I finally get debugger prompt, what means that process finished correctly and we can access FR5969.

Final test

MSP430F5529LP

Please download MSP430F55xx_1.c and save it as src/main.c. Then run:

1
platformio run -e lpmsp430f5529_25

If you see blinking red P1.0 LED1 then everything works as expected.

MSP430FR5969

Please download msp430fr59xx_1.c and save it as src/main.c. Then run:

1
platformio run -e lpmsp430fr5969

If you see blinking green LED2 then everything works as expected.

Summary

I hope that this post was useful for you and you learn some things. If you feel that this knowledge was valuable please share, if you experienced some other problems please let me know, so I can improve content of this post.

UEFI Application development in OVMF

| Comments

OVMF (Open Virtual Machine Firmware) is a project that aim is to enable UEFI support in various virutal machines. According to whitepaper various projects have interest in supporting OVFM ie. VirtualBox, Xen, BHyVe and of course QEMU. Why someone may be interested in OVMF ?

  • IMHO the most important reason is that OVMF give ability to develop UEFI applications without using real hardware. This speeds up development cycle by giving ability to start before hardware prototype arrive. There are also cases when hardware is available only remotely, dealing with remote setup is usually annoying, so part of development can be performed locally.

  • It also improve testing and debugging, because we have full control over execution environment internals. Error injection and corner case analysis can be ineffective in real world. OVMF and qemu open debugging to new levels.

  • It enables training and learning environment. Not every one can obtain UEFI PC and mess with it when there is risk of destroying sth.

  • Many other reason like ability to test/develop UEFI support for various OSes, simplified debugging, lack of dependencies on legacy address space and devices. This and other interesting reasons can be found in Laszlo Ersek whitepaper

What I want to show below is procedure for setting up development environment for UEFI applications and show how to compile and deploy Hello World application in that environment.

QEMU

Let’s use upstream version of QEMU:

1
2
3
4
5
6
git clone https://github.com/qemu/qemu.git 
cd qemu
git submodule init
git submodule update
./configure --target-list=x86_64-softmmu
make -j$(nproc)

Prepare application image

Of course size depends on you application requirements. Usually 128MB is way too much.

1
2
3
dd if=/dev/zero of=app.disk bs=1 count=1 seek=$(( (128 * 1024 * 1024) - 1))
sudo mkfs.vfat app.disk
cd ..

EDK2

First build UEFI firmware with shell:

1
2
3
4
git clone https://github.com/tianocore/edk2.git
cd edk2
nice OvmfPkg/build.sh -a X64 -n $(nproc)
cp Build/OvmfX64/DEBUG_GCC4?/FV/OVMF.fd ovmf.flash

Now we need some application that can be delivered over app.disk to virtual machine. There are couple examples of UEFI applications in edk2 source code, but let’s start with classical Hello World. Source code can be found in MdeModulePkg/Application/HelloWorld. This module is built in MdeModulePkg because of that we can built it as follows:

1
2
source edksetup.sh
build -a X64 -p MdeModulePkg/MdeModulePkg.dsc -t GCC49 -n$(nproc)

Let’s put it into app.disk:

1
2
3
4
5
mkdir mnt_app
cp ../qemu/app.disk .
sudo mount app.disk mnt_app
sudo cp Build/MdeModule/DEBUG_GCC49/X64/HelloWorld.efi mnt_app
sudo umount mnt_app

OVMF configuration

When we develop UEFI application best way would be to run OVMF to UEFI Shell for test purposes. This is not default option. How to change boot order so we every time will lend in shell ?

On booting screen hit <Esc>.

You should be in main menu of UEFI setup:

Go through Boot Maintenance Manager -> Boot Options -> Change Boot Order, select Change Boot Order and hit <Enter>. Then using +/- keys move EFI Internal Shell to the top.

Do not forget to save configuration with <F10>.

Run HelloWorld.efi

To boot OVMF I’m using Laszlo’s slightly modified script which can be found here.

After booting to UEFI Shell we should look something like this:

Note FS0: in mapping table list – this is our app.disk.

Type:

1
2
fs0:
HelloWorld.efi

Result should look like this:

NOTE: If your result is different then make sure to check last lines of app.ovmf.log it can give you some hints.

Summary

Hopefully at least part of above article was useful somehow. There are many ways to extend this sample presentation. In example application delivery can be achieved by network transfer. If you have any question or need UEFI support please do not bother to ping me in comments or using any other medium.

Linux, RPi and USB over IP updated

| Comments

Because of increasing interesting in USB over IP topic I decided to refresh my old post. I will focus on doing the same thing with more recent version of Raspabian. If you need more information please read my previous post.

Setup SD card

First get recent version of Raspbian, then unzip and dd it to SD card:

1
sudo dd bs=4M if=2015-09-24-raspbian-jessie.img of=/dev/sdc

If you are impatient and want to know what happen in background you can use this method of tracking dd progress:

1
sudo sh -c "while true; do killall -USR1 dd; sleep 1; done"

Before removing card we have to be sure that all data were wrote to card:

1
sync

If this operation takes time you can watch progress work writeback and dirty kilobytes using:

1
watch grep -e Dirty: -e Writeback: /proc/meminfo

When sync will finish you can remove SD card and sanity check booting on RPi.

Kernel for RPi

After booting you should be able to ssh to your RPi and check if USBIP was compiled in your kernel.

1
2
3
4
5
6
pi@raspberrypi ~ $ sudo modprobe configs
pi@raspberrypi ~ $ zcat /proc/config.gz |grep USBIP
CONFIG_USBIP_CORE=m
CONFIG_USBIP_VHCI_HCD=m
CONFIG_USBIP_HOST=m
# CONFIG_USBIP_DEBUG is not set

Great! It looks like both server and client support was compiled as modules in recent Raspbian.

Run server side of usbip

Unfortunately usbip user space tools are not available from scratch and have to be installed:

1
sudo apt-get install usbip

Then you can run server:

1
2
3
pi@raspberrypi ~ $ sudo modprobe usbip-core
pi@raspberrypi ~ $ sudo modprobe usbip-host
pi@raspberrypi ~ $ sudo usbipd -D

Without connecting anything we get only internal Ethernet device when listing:

1
2
3
pi@raspberrypi ~ $ usbip list -l
 - busid 1-1.1 (0424:ec00)
    Standard Microsystems Corp. : SMSC9512/9514 Fast Ethernet Adapter (0424:ec00)

Let’s put some memory stick and check again:

1
2
3
4
5
6
pi@raspberrypi ~ $ usbip list -l
 - busid 1-1.1 (0424:ec00)
   Standard Microsystems Corp. : SMSC9512/9514 Fast Ethernet Adapter (0424:ec00)

 - busid 1-1.2 (0951:1666)
   Kingston Technology : unknown product (0951:1666)

Good usbip see our storage device. Let’s try to bind it:

1
2
3
pi@raspberrypi ~ $ sudo usbip --debug bind -b 1-1.2
usbip: debug: /build/linux-tools-06nnfo/linux-tools-3.16/drivers/staging/usbip/userspace/src/usbip.c:141:[run_command] running command: `bind'
usbip: info: bind device on busid 1-1.2: complete

Client side

Let’s check if device was correctly exposed by server on RPi. Of course we need usbip package installed.

1
2
3
4
5
6
7
[13:28:50] pietrushnic:~ $ sudo usbip list -r 192.168.0.105
Exportable USB devices
======================
 - 192.168.0.105
      1-1.3: Toshiba Corp. : TransMemory-Mini / Kingston DataTraveler 2.0 Stick (2GB) (0930:6544)
           : /sys/devices/platform/soc/20980000.usb/usb1/1-1/1-1.3
           : (Defined at Interface level) (00/00/00)

Information is even more accurate then on RPi. Of course 192.168.0.105 have to be replaced with you IP address.

Quickly check if client support correct modules:

1
2
3
4
5
[13:18:36] pietrushnic:~ $ grep USBIP /boot/config-`uname -r`
CONFIG_USBIP_CORE=m
CONFIG_USBIP_VHCI_HCD=m
CONFIG_USBIP_HOST=m
# CONFIG_USBIP_DEBUG is not set

Everything looks ok. Let’s load hos module:

1
sudo modprobe vhci-hcd

Now we can attach remote storage:

1
sudo usbip attach -r 192.168.0.105 -b 1-1.3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[13:29:15] pietrushnic:~ $ sudo fdisk -l /dev/sdd 
GPT PMBR size mismatch (13695 != 3911615) will be corrected by w(rite).
Disk /dev/sdd: 1.9 GiB, 2002747392 bytes, 3911616 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 2164228A-0AD4-43A8-9478-0E94701363B1

Device     Start   End Sectors  Size Type
/dev/sdd1   2048 13662   11615  5.7M EFI System
[13:29:27] pietrushnic:~ $ sudo mount /dev/sdd1 tmp
[13:29:39] pietrushnic:~ $ ls tmp 
EFI  shellia32.efi  shellx64.efi  shellx64-refind-signed.efi

Let’s left some signs:

1
2
3
[13:30:55] pietrushnic:~ $ sudo sh -c "echo DEADBEEF > tmp/foobar"
[13:31:08] pietrushnic:~ $ cat tmp/foobar 
DEADBEEF

Detach and see if we will see this file on server side:

1
2
3
4
5
6
7
8
[13:33:31] pietrushnic:~ $ sudo usbip port
Imported USB devices
====================
Port 00: <Port in Use> at High Speed(480Mbps)
       unknown vendor : unknown product (0930:6544)
       5-1 -> usbip://192.168.0.105:3240/1-1.3
           -> remote bus/dev 001/005
[13:33:39] pietrushnic:~ $ sudo usbip detach -p 0

First let’s unbind:

1
2
pi@raspberrypi ~ $ sudo usbip unbind -b 1-1.3
usbip: info: unbind device on busid 1-1.3: complete

Then mount partition on which we placed out test file:

1
2
3
pi@raspberrypi ~ $ sudo mount /dev/sda1 tmp/
pi@raspberrypi ~ $ cat tmp/foobar 
DEADBEEF

Summary

This is quick refresh for those struggling with running usbip. There many topics to cover in this area I think about writing posts related to below topics:

  • usbip on Raspberry Pi 2
  • passing frames for RS232 to USB converter using usbip
  • A20-OLinuXino-MICRO/Cubietruck and usbip

If you any other preference or topics that would like to see on this blog please let me know in comments. If you think this post can be useful for others please share.

Thanks for reading.