Sunday 30 June 2013

Report 2 (June 24 - June 30)

This is Report #2. I plan to post these every Sunday. They will give a rundown of what I've done during the week, list any problems I had, and what I plan to do the following week. I'll be posting the reports both to the beagle-gsoc Google Group and to my blog.

Completed this week:
  • Rebased against mainline Minix.
  • Collaborated with mentors and other developers on a design document.
  • Finished the i2c bus read function.
  • Developed the i2c bus write function.
  • Implemented the NetBSD/OpenBSD i2c /dev interface.
  • Imported i2cscan from NetBSD into the my source tree.
  • Started working on a CAT24C256 EEPROM test program that uses the /dev interface.
  • Put an EEPROM on a bread board and started testing some of the i2c buses on the BBB. See my blog post for details.
Issues / Concerns / Challenges:
  • I spent several hours trying to get the i2cscan program from NetBSD working right. It turns out the i2c controllers on the am335x and dm37xx don't support i2cscan's method of probing devices on the bus in most address ranges. For most ranges of slave addresses, i2cscan attempts 0 byte writes (i.e. quick writes). The i2c controllers on the am335x and dm37xx treat a 0 count as 65536. The end result is that only a few i2c devices are detected by i2cscan. It can detect a few devices in some slave address ranges because it attempts a 1 byte read in those ranges. To get around this issue, I will be adding a command line option ('-r') to scan all slave address ranges via the one byte read method. This '-r' option would work the same as the '-r' option that the i2cdetect program from i2c-tools provides.
Plan for next week:
  • Enhance usr.sbin/i2cscan to support scanning using only the 1 byte read method (i.e. make it work similar to i2cdetect -r). Submit patches upstream to NetBSD.
  • Finish developing the test program. It's basically going to write to specific locations in the EEPROM and read back what it wrote.
  • More Testing. Use the EEPROM test program on the various i2c buses on the BeagleBone Black and BeagleBoard-xM. Fix any bugs.
  • Define the interface for accessing the i2c bus from other drivers, document on Minix wiki (or at least write the documentation so it can be posted to the wiki later).
  • Implement a way for drivers to "claim" devices on the bus so that user programs and unrelated drivers don't interfere with the device.
  • Start work on an eeprom driver.

Friday 28 June 2013

Testing this Morning

I've been making good progress on my generic driver for the i2c bus as well as the /dev interface. I decided that I've gotten far enough along that I can start doing some testing. For testing, I'm using a CAT24C256 EEPROM on a bread board. This is the same chip that's used in the capes (expansion boards) for the BeagleBone. My test setup has one of those chips on a bread board. It's a fairly basic setup... connect 3.3V and GND, connect SCL/SDA to the right pins on the connector (with 5.6K pull-up resistors), and set the address pins. Details about the pins on the BBB's connectors and a schematic for the EEPROM can be found in the System Reference Manual. Here's a photo of my setup with the EEPROM on the 2nd I2C bus with an address of 0x50:

http://tomcort.com/gsoc/testjig.jpgI imported the i2cscan program from NetBSD into my source tree and it was able to discover the chip:

http://tomcort.com/gsoc/i2cscan-found-eeprom.png

I've got another test program that can read from specific memory locations within the EEPROM. I'm going to enhance it to perform writes to specific locations. Then I'll be able to test reading what I've written. I'll repeat the steps on the 3rd i2c bus and then again on the buses of the BeagleBoard-xM.



Sunday 23 June 2013

Report 1 (June 17 - June 23)

This is the first of many weekly reports. I plan to post these every Sunday. They will give a rundown of what I've done during the week, list any problems I had, and what I plan to do the following week. I'll be posting the reports both to the beagle-gsoc Google Group and to my blog.

As this is my first report, I'm including links to all of the project resources:
Completed this week:
  • Rebased the skeleton code I had developed when writing my GSoC application.
  • Extracted the clock configuration code from libgpio and put it into it's own library, libclkconf. Merged.
  • Used libclkconf to configure the clocks for i2c. I2C_REV is now readable on all buses on the BeagleBone Black and BeagleBoard-xM.
  • Wrote code to configure the pins with libpadconf. Need to finish more of the driver to completely test this.
  • Removed duplicate code in libpadconf. Merged.
  • Implemented the i2c initialization procedure described in the TRM.
  • Began work on a read function. It isn't complete yet, but it can read the magic number and board name from the on board EEPROM on the BeagleBone Black. Screenshot.
  • Setup netbooting and figured out how to transfer files with ZMODEM. This will improve my productivity a lot. Documented procedure on the project blog (netboot, serial transfer) and Minix wiki (netboot, serial transfer).
  • Received a BeagleBoard-xM from TI. Thanks TI! Tried it out and made a blog post about running Minix on the BeagleBoard-xM. Will use it for developing/testing Minix i2c support for the dm37xx.
  • Received a Welcome Package from Google. Thanks Google!

Issues / Concerns / Challenges:
  • The files for the stage 1 bootloader and u-boot are downloaded from the Minix website when doing a fresh build of an SD card image. Once this week, the website was down for a few minutes and I couldn't do a build. To prevent this from happening again, I setup a local mirror on my computer.
  • Writing 2GB SD card images to the uSD card is time consuming. It takes about 7 minutes with my class 4 card. I'd prefer a much faster write, compile, test cycle. To overcome this issue, I setup a netboot environment and will use zmodem to transfer my changes (usually just 1 file).

Plan for next week:
  • Clean up and finish the read function. Get it working on the BeagleBoard-xM as well.
  • Implement the write function.
  • Put some EEPROMs on a bread board and test reading and writing data on all of the buses to confirm proper pin configuration and test read/write functions.
  • As time permits, begin implementing the /dev interface.

Saturday 22 June 2013

Transfering files over serial to Minix/arm using ZMODEM

Since Minix doesn't have a network driver for the BeagleBone Black yet and swapping out the SD card all the time just to put one or two files on it is labour intensive, we need to find another way to (relatively) quickly transfer files from the development machine to the BeagleBone. Luckily, there are tools which can help us in this area.

The terminal program I use to interact with the BeagleBone over the serial connection, picocom, can use an external program, lrzsz, to support transfers using the ZMODEM protocol. It just so happens that Minix provides a ZMODEM implementation too. This combination is easy to setup and can transfer files to the bone for us. This guide explains how to setup and use it.

The first step is to install lrzsz on your development machine.
emerge lrzsz
Then, create a test file so we have something to try transfering.
echo "Hallo, Wereld" > test.txt

Next, start picocom with these options.
picocom -b 115200 /dev/ttyUSB0 --send-cmd "sz -vv -y"
Then, boot Minix. Need a hint? Try my other guides: Minix on the BeagleBone Black (Part 1, Part 2, Part 3), Netbooting Minix on the BeagleBone Black, Minix on the BeagleBoard-xM. Once you've gotten Minix up and running, you can log in as root and proceed to the next step.

Do Ctrl-a+s a to initiate a transfer (i.e. hold down the control key, press and release 'a', press and release 's', and finally release the control key). You will be prompted to enter the name of the file you want to transfer. Below I entered the name of the example file (test.txt) and pressed the enter key. The transfer should go and end with "*** exit status: 0" Here's what the output looks like:

#
*** file: test.txt
sz -vv -y test.txt
Sending: test.txt
Bytes Sent:     14   BPS:14                             

Transfer complete

*** exit status: 0
# cat test.txt
Hallo, Wereld
#

Netbooting Minix on the BeagleBone Black

This guide will cover how to setup booting Minix on the BeagleBone Black over a wired network. Before you begin, you need to gather some hardware. You'll need a hub or a switch, 2 ethernet cables, a BeagleBone Black, and a server/development machine (it's easier if these are both are the same machine). The first step is to build Minix.

You'll need some sort of Linux or Unix-like system to build Minix. The system should have at least the following tools installed: git, bash, sfdisk, mcopy, dd, wget, mkfs.vfat, make, and a C compiler. Once you've got the tools installed, the next step is to get the source code from my minix-i2c repository on github and checkout the i2c branch.

cd $HOME
git clone git://github.com/tcort/minix-i2c.git
cd minix-i2c
git checkout i2c
echo "BASE_URL=http://www.minix3.org/arm/beaglebone" > .settings
echo "FLAG=-DAM335X" >> .settings
echo "CONSOLE=tty00" >> .settings
There is one option you have to add to tell u-boot to boot over the network. Edit $HOME/minix-i2c/releasetools/arm_sdimage.sh (add a -n to the gen_uEnv.txt.sh line). That line should end up looking like this:
./releasetools/gen_uEnv.txt.sh -n > ${IMG_DIR}/uEnv.txt
Build an SD card image.
./releasetools/arm_sdimage.sh
Insert your SD card into your SD card reader/writer. Check the output of `dmesg` to see which device file it was mapped to. If you aren't paying attention here, you could write the SD card image to your hard drive by accident, destroying your partition table and boot sector in the process. If your card had file systems on it previously and your computer auto-mounted them, you should unmount them all after backing up any files you wish to keep. Then, write the image to the SD card with dd using the command below, changing /dev/sdX to match the device file for the SD card.
dd if=minix_arm_sd.img of=/dev/sdX bs=1M oflag=direct
While the card is being written, you can setup the network and the server. Apply power to the hub or switch and connect an ethernet cable to it from the server computer and the BeagleBone Black.

The following instructions are for Gentoo Linux, but there aren't a lot of Gentoo specific commands here. The package installation will be different for different distributions as well as network configuration.

While there are several tftp servers to choose from, I prefer dnsmasq. dnsmasq is easy to configure and provides a lot of other useful services (dns, dhcp, ...), so I chose that one. The built-in tftp and dhcp servers need to be enabled at build time. In Gentoo, you do that by setting tftp and dhcp USE flags in /etc/portage/make.conf:
USE="tftp dhcp"
Then install dnsmasq:
emerge dnsmasq
In the configuration, I chose the 192.168.12.0/24 network for no other reason than the default configuration for Minix's netboot is designed around that network. The settings can be changed in releasetools/gen_uEnv.txt.sh if you really want something else, but that just adds more steps and potential traps.

The next step is to configure dnsmasq. Set interface to the ethernet interface connected to your netboot network. Optionally set the dhcp pool range if you want to enable dhcp. Finally, enable TFTP and point it to the object directory. It should be called obj.evbearm-el and be placed one level above the Minix source directory (in this case, $HOME/obj.evbearm-el). My /etc/dnsmasq.conf looks like this:

# Listen only to this interface
interface=eth0

# Enable DHCP server and define the range of addresses in the pool
dhcp-range=192.168.12.75,192.168.12.175,255.255.255.0,12h

# Enable the TFTP server and set the root directory.
enable-tftp
tftp-root=/home/tcort/repos/i2c/obj.evbearm-el/
Configure the ethernet interface connected to your network. Again, the IP address was chosen because it's the default for Minix netboot and I didn't want to mess with the defaults. On Gentoo, add the following line to /etc/conf.d/net
config_eth0="192.168.12.10 netmask 255.255.255.0 brd 192.168.12.255"
Configure the init system to bring up the NIC and dnsmasq at boot as well as right now.
ln -s /etc/init.d/net.lo /etc/init.d/net.eth0
/etc/init.d/net.eth0 start
rc-update add net.eth0 default
/etc/init.d/dnsmasq start
rc-update add dnsmasq default
Now take your MicroSD card and insert it into the MicroSD card slot on the bottom side of the BeagleBone with the label facing up, pads facing down. Next, attach the FTDI USB-Serial Cable. Be sure you're using the 3.3V version of the cable, and also be sure that it's oriented correctly. Pin 1 is marked on the board with a white dot, it's closer to the ethernet connector than the MicroSD card slot. Pin 1 on the connector is marked with a small arrow and the insulator of the wire going to pin 1 should be black. Now plug the USB side of the USB-Serial cable into your computer. The driver should be loaded automatically. Use `dmesg` or `ls /dev/ttyUSB*` to see what device file to use in the next step. It will most likely be /dev/ttyUSB0 unless you have other USB to Serial adaptors plugged in. You can use pretty much any terminal program. I use picocom for no particular reason other than it is the first one I tried, and it worked. Most programs have the proper default settings except for the baud rate which needs to be set to 115200 BAUD. Here's how to invoke picocom:
picocom -b 115200 /dev/ttyUSB0
The final step, once the terminal program is running, is to plug in the BeagleBone to a power supply. This should cause it to start booting. It will default to the MicroSD card, read the netboot configuration, and should start netbooting Minix automatically. There will be some output from the bootloader and eventually Minix will start loading via TFTP. Here's a snippet of some of the output:
...
link up on port 0, speed 100, full duplex
Using cpsw device
TFTP from server 192.168.12.10; our IP address is 192.168.12.62
Filename 'kernel.bin'.
Load address: 0x80200000
Loading: #################
     1.2 MiB/s
done
...
Eventually, you'll be presented with a login prompt. The default login is "root" with no password. That will give you a shell where you can issue commands. As the project progresses, I'll be making posts explaining how to get started with i2c on Minix. When you're done, you can issue the `halt` command. Minix will stop itself and print a message saying that it's okay to turn off the computer. At this point, you can remove the power supply and unplug the USB cable from your computer.

Thursday 20 June 2013

Minix on the BeagleBoard-xM

Previously I posted about running Minix on the BeagleBone Black (1, 2, 3) and inside a Linaro QEMU virtual machine. Today I'm writing about getting Minix up and running on the BeagleBoard-xM.

You'll obviously need a BeagleBoard-xM for this. In addition to that, you'll need a way to connect to the xM's serial port. If you have an older computer with a serial port, a serial cable will do. Otherwise, you'll need a USB to Serial cable. This will enable you to connect your development machine to the BeagleBoard-xM's serial port via USB. With almost any terminal program you'll be able to interact with the Minix command line interface. While you can power the BeagleBoard-xM over USB, it may be more convenient (and more reliable) to just get an AC adaptor and plug it into mains power. The adaptor I link to below has clips with different prongs for connecting to outlets in different countries. Choose the right one for your country. Lastly, you'll need an SD card with at least 2GB of storage. Fortunately, one comes with the xM.

Shopping List:
You'll need some sort of Linux or Unix-like system to build Minix. The system should have at least the following tools installed: git, bash, sfdisk, mcopy, dd, wget, mkfs.vfat, make, and a C compiler. Once you've got the tools installed, the next step is to get the source code from my minix-i2c repository on github and checkout the i2c branch.
cd $HOME
git clone git://github.com/tcort/minix-i2c.git
cd minix-i2c
git checkout i2c
The next steps of building a cross compiler, cross compiling Minix, and creating an SD card image have been automated. You just need to set a few environment variables and run a script.

echo "BASE_URL=http://www.minix3.org/arm/beagleboard-xm" > .settings
echo "FLAG=-DDM37XX" >> .settings
echo "CONSOLE=tty02" >> .settings
./releasetools/arm_sdimage.sh
After a lot of compiling, you'll be left with an image file in the current working directory named minix_arm_sd.img

Insert your SD card into your SD card reader/writer. Check the output of `dmesg` to see which device file it was mapped to. If you aren't paying attention here, you could write the SD card image to your hard drive by accident, destroying your partition table and boot sector in the process. If your card had file systems on it previously and your computer auto-mounted them, you should unmount them all. Then, write the image to the SD card with dd.
dd if=minix_arm_sd.img of=/dev/sdX bs=1M oflag=direct
After several minutes or more, dd will finish and you can remove the card. I'm not sure if it makes a difference or not, but I usually issue the sync command before removing the card just to make sure that all of the data was actually flushed to the card.

The first step is to take your MicroSD card and insert it into the MicroSD card slot on the bottom side of the board with the label facing up, pads facing down. Next, attach the serial or USB to serial cable to your board and your computer. The driver should be loaded automatically if you're using a USB to serial cable. Use `dmesg` or `ls /dev/ttyUSB*` to see what device file to use in the next step. It will most likely be /dev/ttyUSB0 unless you have other USB to Serial adaptors plugged in. You can use pretty much any terminal program. I use picocom for no particular reason other than it is the first one I tried and it worked. Most programs have the proper default settings except for the baud rate which needs to be set to 115200 BAUD. Here's how to invoke picocom:
picocom -b 115200 /dev/ttyUSB0
The final step, once the terminal program is running, is to plug in the BeagleBoard-xM to a power supply. This should cause it to start booting. It will default to the MicroSD card and should start Minix automatically. Eventually, you'll be presented with a login prompt. The default login is "root" with no password. That will give you a shell where you can issue commands. As the project progresses, I'll be making posts explaining how to get started with i2c on Minix.

When you're done, you can issue the `halt` command. Minix will stop itself and print a message saying that it's okay to turn off the computer. At this point, you can remove the power supply and unplug the USB cable from your computer.

Wednesday 5 June 2013

Minix on Linaro QEMU

Previously, I had written several posts about running Minix on the BeagleBone Black (Parts: 1, 2, 3). While running an operating system on real hardware is usually preferable to running inside an emulator, sometimes you want to try something out quickly without waiting 10 minutes for an image to get written to an SD card or maybe you don't have a specific piece of hardware in hand. This is where an emulator comes in handy. Luckily, there is a not-for-profit engineering organization at Linaro.org that helps out the open source ARM community. They've got a customized version of QEMU which does a decent job of emulating the BeagleBoard-xM. This guide will step you through building Linaro QEMU, building Minix, and booting the system.

The first step is to get the source code for the Linaro version of QEMU, build it, and install it. The commands below can be executed as a normal user and install QEMU to the 'qemu' directory under your home directory. You may have to adjust the path to python for your operating system. If you are missing any required libraries or tools, the configure script will let you know. The instructions suggest a specific revision to ensure that you get the best results with Minix. Don't ignore that suggestion.

cd $HOME
git clone git://git.linaro.org/qemu/qemu-linaro.git
cd qemu-linaro
git checkout 72f7eb07b611766298fe2dc140533a0a6256b054
./configure --target-list=arm-softmmu \
--prefix=$HOME/qemu \
--python=/usr/bin/python2.7

make
make install
Once you have the emulator software installed, you need to create an SD card image file containing the Minix base system. These commands will walk you through checking out my code, configuring the build, and building the whole system. Again, if you need any libraries or tools, the arm_sdimage.sh script will let you know about it.

cd $HOME
git clone git://github.com/tcort/minix-i2c.git
cd minix-i2c
git checkout i2c
echo "BASE_URL=http://www.minix3.org/arm/beagleboard-xm" > .settings
echo "FLAG=-DDM37XX" >> .settings
echo "CONSOLE=tty02" >> .settings
./releasetools/arm_sdimage.sh

Now, if everything was successful, you should have the emulator installed and a complete Minix operating system image ready to boot. The next step is to fire up the emulator with it pointed at the SD card image file.

cd $HOME/minix-i2c && $HOME/qemu/bin/qemu-system-arm \
-M beaglexm -drive \
if=sd,cache=writeback,file=minix_arm_sd.img  \
-clock unix -serial stdio -device usb-kbd \
-device usb-mouse -usb
That should boot up Minix and present you with a login prompt. The default login is "root" with no password. That will give you a shell where you can issue commands. As the project progresses, I'll be making posts explaining how to get started with i2c on Minix. I will also write about running Minix on an actual BealgeBoard-xM.

When you're done, you can issue the `halt` command. Minix will stop itself and print a message saying that it's okay to turn off the computer. At this point, you can press Ctrl+C to terminate qemu.