Move ThinkPenguin CCS case study to first one.
The original text for this case study was developed as the final
chapter, as sort of a "you heard about the rest, now try the best"
approach.  However, I think we want to put this one first.  "Hope before
despair" is perhaps a better attitude?
The diff on this one didn't come out so clean, so it's a bit difficult
to see that I'm just moving  a big block of text up.
I diffed it against a version of this file, from:
  commit 2f2e5f9e4c on 2014-10-15 22:14:45 -0400
that was before work began on this chapter, and the diff was relatively
clean.
			
			
This commit is contained in:
		
							parent
							
								
									983b035d68
								
							
						
					
					
						commit
						72f50f68ea
					
				
					 1 changed files with 299 additions and 300 deletions
				
			
		|  | @ -239,6 +239,305 @@ compliance. We have received the gamut of possible reactions to such | |||
| requests, and in this course, we examine four specific examples of such | ||||
| compliance work. | ||||
| 
 | ||||
| % FIXME: make this section properly TeX-formatted | ||||
| \chapter{ThinkPenguin Wireless Router: A study in Excellent CCS} | ||||
| 
 | ||||
| This case study does a step-by-step build and installation analysis of  one | ||||
| of the best Complete, Corresponding Source (CCS) releases we've seen.  The | ||||
| CSS release studied here was provided for the binary distribution of a | ||||
| physical product by ThinkPenguin.  The product is the model | ||||
| ``TPE-NWIFIROUTER'', a wireless router. | ||||
| 
 | ||||
| The method of | ||||
| distribution (complete source accompanying the product) and the way the source | ||||
| was laid out provide very good examples of how to make things easier for both | ||||
| the distributor and the purchaser of the hardware containing GPLed components. | ||||
| 
 | ||||
| \section{Root Filesystem and Kernel Compilation} | ||||
| 
 | ||||
| * We found a CD included in the box that the ThinkPenguin TPE-NWIFIROUTER | ||||
|   shipped in, labelled "libreCMC v1.2.1 source code".  On the CD, there was a | ||||
|   README file at the top level, which mentioned that to build the software, one | ||||
|   needed a GNU/Linux system as well as a list of approximately 10 packages. | ||||
|   These sorts of plain text instructions are helpful because we know what kind | ||||
|   of system we are expected to use, and what commands we should run on it.  Such | ||||
|   instructions are not strictly required, as an obviously-named shell script may | ||||
|   suffice, but they are helpful in clarifying any ambiguities that may arise. | ||||
| ** Since it appears that this source release will build on a wide range of | ||||
|    distributions, it was fine that no specific distribution was specified. | ||||
|    However, most source releases we see will only build on a very specific | ||||
|    distribution, due to a variety of assumptions made about the build | ||||
|    environment.  While such a situation is not ideal in the general sense, it is | ||||
|    fine to specify a particular distribution that must be use to build the | ||||
|    source release (such as "Debian 7 amd64"), from a compliance perspective. | ||||
|    As an example, we noticed such an assumption later on in this source release, | ||||
|    but it would be easy to correct in the instructions in this situation (see | ||||
|    "`GLIBC\verb0_02.14' not found" below). | ||||
| 
 | ||||
| % FIXME: Spend some  time here (admittedly a digression: maybe refer to | ||||
| % another section later?) about how it's ok to specify a specific build | ||||
| % environment. | ||||
| % FIXME(dg): Hopefully the above will suffice.  I can expand more/differently if | ||||
| % such is desired. | ||||
| 
 | ||||
| * The actual building of the source code was completed in the following way: | ||||
| ** Since the instructions didn't mention a specific distro to use, we ran the | ||||
|    build on an amd64 Debian 6 machine we had.  The only distro requirement was: | ||||
| 
 | ||||
| To build your own firmware you need to have access to a GNU/Linux system | ||||
| (case-sensitive filesystem required). | ||||
| 
 | ||||
| ** The README mentioned that: | ||||
| 
 | ||||
| "In order to build firmware images for your router,the | ||||
| following needs to be installed : | ||||
| 
 | ||||
| gcc, binutils, bzip2, flex, python, perl, make, find, | ||||
| grep, diff, unzip, gawk, getopt, libz-dev and libc headers." | ||||
| 
 | ||||
|    So we ran "dpkg --list" and confirmed that each package was installed (this | ||||
|    is indicated by a leading "ii" on the line containing the package).  Other | ||||
|    GNU/Linux distributions may have other ways of determing which packages are | ||||
|    installed. | ||||
| ** We then extracted the LibreCMC tarball by running | ||||
|    "tar --posix -jxpf /media/libreCMC\verb0_0v1\verb0_02\verb0_01\verb0_0SRC/librecmc-v1.2.1.tar.bz2".  The | ||||
|    CD did contain another tarball (librecmc-u-boot.tar.bz2), but there appeared | ||||
|    to be separate instructions for that (in the u-boot\verb0_0reflash text file in the | ||||
|    same directory).  Having the README be more explicit about this would be nice | ||||
|    but did not ultimately prevent us from determing the proper steps to execute. | ||||
| ** The README mentioned the following optional step, which we skipped because | ||||
|    we did not need to modify the configuration for our initial build: | ||||
| 
 | ||||
| Please use "make menuconfig" to configure your appreciated | ||||
| configuration for the toolchain and firmware. Please note that | ||||
| the default configuration is what was used to build the firmware | ||||
| image for your router. It is advised that you use this configuration. | ||||
| 
 | ||||
| ** The next instruction was 'Simply running "make" will build your firmware.' | ||||
|    So we entered the "librecmc" directory that had been created from the above | ||||
|    "tar" command and then ran "make".  The build took about 40 minutes to run on | ||||
|    our system.  The command used and output from running it are available here: | ||||
| 
 | ||||
|     enforcement-case-studies\verb0_0log-output/thinkpenguin\verb0_0librecmc-complete.log | ||||
| 
 | ||||
| % FIXME: Above, I'd like to see more ``walk through'' of the step by step | ||||
| % instructions.  The text is a bit terse: could be expanded to talk more. | ||||
| % FIXME(dg): Hopefully the above will suffice.  I can expand more/differently if | ||||
| % such is desired. | ||||
| 
 | ||||
| * It was helpful to know that we could use "make menuconfig" for configuration | ||||
|   changes, as being able to modify the source is an important part of the GPL's | ||||
|   requirements.  Adding instructions like these shows that the distributor is | ||||
|   aware of and interested in promoting the spirit of the GPL, by making it | ||||
|   easier to modify the source than may be strictly required by the GPL's text. | ||||
| 
 | ||||
| % FIXME: We should somewhere (perhaps on each step we discuss) talk about | ||||
| % what often goes wrong on those steps, and why this is right.  As written | ||||
| % now, there is no driving home of the fact that it is uncommon that things | ||||
| % are so smooth. :) | ||||
| % FIXME(dg): Hopefully the below will suffice.  I can expand more/differently if | ||||
| % such is desired.  (I presume the above comment relates to the below text.) | ||||
|    | ||||
| * The "make" step completed successfully on our system and resulted in several | ||||
|   files being generated in the bin/ar71xx directory, namely firmware images. | ||||
| ** This step is normally where we run into the greatest number of build issues | ||||
|    (and thus compliance problems).  In many cases, the "make" step will fail due | ||||
|    to a missing package or because toolchain paths are not setup correctly.  As | ||||
|    a result, it is important to test the provided instructions on a clean system | ||||
|    before distributing the binaries and corresponding source.  Listing the | ||||
|    specific GNU/Linux distribution and any non-default packages required for the | ||||
|    build (ie. those installed before testing the instructions) in the build | ||||
|    instructions makes it easier for the end user to successfully build the | ||||
|    source release. | ||||
| 
 | ||||
| * There appeared to be several filesystem and kernel images, for different | ||||
|   hardware versions.  It was unclear which one to install on the particular | ||||
|   device we received or how to install it, both of which should have been | ||||
|   mentioned in the README. | ||||
| 
 | ||||
| % FIXME: Below, we probably want to talk to them to add this, and also, be a | ||||
| % bit more expansive. | ||||
|    | ||||
| * The above installation issue is mitigated by the availability of a web UI in | ||||
|   the product that performs firmware image installation.  It would be best if | ||||
|   instructions like those at http://librecmc.org/librecmc/wiki?name=Tp+MR3020 | ||||
|   were included in the README, as the user cannot be expected to infer that or | ||||
|   to find such a link. | ||||
| 
 | ||||
| \section{Root Filesystem and Kernel Installation} | ||||
| 
 | ||||
| As mentioned above, the specific steps for installing an updated firmware image | ||||
| were not provided, but we found that the firmware update method available in the | ||||
| web interface worked fine.  In particular, we went to http://192.168.10.1/ in | ||||
| our browser, then logged in and chose System -> Backup / Flash Firmware.  From | ||||
| there, we went to the "Flash new firmware image" section and selected the | ||||
| librecmc-ar71xx-generic-tl-wr841n-v8-squashfs-sysupgrade.bin image in the | ||||
| bin/ar71xx directory mentioned above.  We chose the "v8" image because we found | ||||
| our router said "v8.2" on the bottom and "sysupgrade" because we were doing a | ||||
| firmware upgrade rather than a fresh install. | ||||
| 
 | ||||
| When we clicked "Flash image...", we were prompted to confirm the MD5 hash of | ||||
| the image to flash and then clicked "Proceed" to flash the image.  The process | ||||
| took about one minute, at which point we were back at the web UI login screen. | ||||
| We logged in and found that the Kernel Log section showed we were running the | ||||
| new kernel. | ||||
| 
 | ||||
| We then logged in via SSH again and ran "busybox", which printed the new version | ||||
| string, showing it was using our newly-compiled version (given the date). | ||||
| 
 | ||||
| \section{U-Boot Compilation} | ||||
| 
 | ||||
| * As mentioned above, we also found a "u-boot\verb0_0reflash" file at the top level of | ||||
|   the included source CD.  We followed the instructions for compiling U-Boot, | ||||
|   which were fairly straight-forward.  One modification would be to mention that | ||||
|   "\$U-BOOT\verb0_0SRC" referred to the extracted source directory, which was implied, | ||||
|   but should have been explicit. | ||||
| * Additionally, we noticed that the included toolchain binaries, which were used | ||||
|   by the U-Boot compilation process by default, did not run on our system.  In | ||||
|   particular, we received this error: | ||||
| 
 | ||||
| mips-librecmc-linux-uclibc-gcc.bin: /lib/libc.so.6: version `GLIBC`\verb0_02.14' not found (required by mips-librecmc-linux-uclibc-gcc.bin) | ||||
| 
 | ||||
|   The complete log output (including the command used to run it) is here: | ||||
| 
 | ||||
|      enforcement-case-studies\verb0_0log-output/thinkpenguin\verb0_0u-boot-build\verb0_0fail.log | ||||
| 
 | ||||
| * We found that by removing toolchain/bin and symlinking the toolchain built for | ||||
|   the filesystem/kernel above in its place, we were able to complete the U-Boot | ||||
|   build.  Specifically, we symlinked toolchain/bin to: | ||||
| 
 | ||||
|   ../../staging\verb0_0dir/toolchain-mips\verb0_034kc\verb0_0gcc-4.6-linaro\verb0_0uClibc-0.9.33.2/bin | ||||
| 
 | ||||
|   Output from the symlink operation can be found here: | ||||
| 
 | ||||
|      enforcement-case-studies\verb0_0log-output/thinkpenguin\verb0_0u-boot-create\verb0_0symlink.log | ||||
| 
 | ||||
| * Ideally the pre-built toolchain binaries should not be included and a symlink | ||||
|   as mentioned above should be created by default, with a mention that the | ||||
|   U-Boot build depends on the previous build for its toolchain. | ||||
| * After compilation completed successfully, we found a new U-Boot image in the | ||||
|   bin directory.  The instructions explained how to install it on the device. | ||||
|   Output from the successful build (after the symlink was created) is here: | ||||
| 
 | ||||
|      enforcement-case-studies\verb0_0log-output/thinkpenguin\verb0_0u-boot-finish\verb0_0build.log | ||||
| 
 | ||||
| \section{U-Boot Installation} | ||||
| 
 | ||||
| We obtained a serial cable along with our router, in order to complete the | ||||
| U-Boot installation per the instructions in u-boot\verb0_0reflash.  However, we were | ||||
| only able to read data from the serial port; we were unable to interrupt the | ||||
| boot process or access the U-Boot console to complete the U-Boot re-flash.  Here | ||||
| are the steps we tried: | ||||
| 
 | ||||
| * We found the serial cable included was a USB serial adapter that had a male | ||||
|   USB type A connector on one end and 4 female jumper wires at the other end. | ||||
|   These female jumper wires were red, black, white, and green. | ||||
| * The instructions did not specify how to connect these wires, but we were able | ||||
|   to determine this in part using the "v8.4" image (close to our "v8.2" router) | ||||
|   at \url{http://wiki.openwrt.org/toh/tp-link/tl-wr841nd#serial.console} .  Aside from | ||||
|   power and ground (red and black), we did have to guess which of the wires was | ||||
|   RX and TX.  By experimentation we found that green was RX and white was TX. | ||||
|   When we tried the other way, we received no data to our serial console at boot | ||||
|   time. | ||||
| * We did have to use the included jumper pin gender changer with the USB serial | ||||
|   adapter, which we put through the holes on the router's mainboard and then | ||||
|   connected to the USB serial adapter.  The fit was fairly loose so it would be | ||||
|   nice if future router versions included a tighter gender changer or (ideally) | ||||
|   had the jumper pins soldered onto the board to begin with (so no gender | ||||
|   changer would be required). | ||||
| * We used 115200 8N1 as our serial console settings (with no hardware or | ||||
|   software flow control).  This was tested with both the minicom and screen | ||||
|   commands.  We found that if we connected all 4 wires on the USB serial adapter | ||||
|   that the router would start without additional power and our console would | ||||
|   receive the startup messages.  We could replicate the same behavior by | ||||
|   omitting the power cable from the USB serial adapter (red wire) and connecting | ||||
|   the main power adapter to the router instead. | ||||
| * While we did see the U-Boot and kernel boot logs in our serial console, we | ||||
|   were unable to interrupt the boot process as u-boot\verb0_0reflash indicated we | ||||
|   should.  We suspect this is a misconfiguration of our serial console, but it's | ||||
|   unclear exactly how it is misconfigured, as we were able to receive data fine | ||||
|   (we just couldn't send data to the router). | ||||
| * As a result, we were unable to complete the U-Boot installation test.  We did | ||||
|   appreciate that installation instructions were included, though these | ||||
|   instructions should be updated to include more specifics about connecting the | ||||
|   serial cable.  Since ThinkPenguin does have the option to ship a serial | ||||
|   adapter with the router, it would be helpful if instructions specific to that | ||||
|   adapter were included, as the wiring configuration one should use was unclear. | ||||
| * Additionally, instructions for removing the router's case should be included. | ||||
|   We found that the two screws that needed removal to open the case were hidden | ||||
|   underneath rubber feet on the case.  Indicating which feet need removal to | ||||
|   unscrew the case would be helpful.  The instructions should also note that the | ||||
|   case needs to be carefully separated once the screws are removed; it | ||||
|   effectively snaps apart, but care must be taken to avoid breaking the plastic | ||||
|   fasteners that keep the case together after the screws are removed. | ||||
| 
 | ||||
| \section{Firmware Comparison} | ||||
| 
 | ||||
| To ensure that the CCS did indeed correspond to the firmware that was shipped on | ||||
| the router, we compared the firmware image that we built using the above steps | ||||
| with the filesystem we found on the device itself.  The comparison steps we used | ||||
| were: | ||||
| 
 | ||||
| * Extract the filesystem from the image we built by running find-firmware.pl | ||||
|   from https://gitorious.org/gpl-compliance-tools/gpl-compliance-scripts on | ||||
|   librecmc-ar71xx-generic-tl-wr841n-v8-squashfs-factory.bin from the bin/ar71xx | ||||
|   directory mentioned above (we noticed that our router said "Ver:8.2" on the | ||||
|   bottom).  Then run squashfs4.2/squashfs-tools/bat-unsquashfs42 from | ||||
|   bat-extratools (at http://www.binaryanalysis.org/en/content/show/download ) | ||||
|   on the resulting morx0.squash and use the filesystem in the new squashfs-root | ||||
|   directory for comparison. | ||||
| * Login to the web interface (at http://192.168.10.1/ ) from a computer that is | ||||
|   connected to the router. | ||||
| * Set a password using the provided link at the top (the UI warns that no | ||||
|   password is set and asks the user to change it). | ||||
| * Login to the router via SSH, using the root user and the password we just set. | ||||
| * Compare representative directory listings and binaries to ensure the set of | ||||
|   included files (on the router) is similar to those found in the firmware image | ||||
|   we created (whose contents are now in the local squashfs-root directory).  In | ||||
|   particular, we did the following comparisons: | ||||
| ** List the /bin folder ("ls -l /bin") and confirm the list of files is the same | ||||
|    and that the file sizes are similar. | ||||
| ** Check the "strings" output of /bin/busybox to confirm it was similar in both | ||||
|    places (similar number of lines and content of lines).  One cannot directly | ||||
|    compare the binaries because the slight compilation variations will cause | ||||
|    some bits to be different. | ||||
| ** Do the above two steps for /lib/modules, /usr/bin, and other directories with | ||||
|    a significant number of binaries. | ||||
| ** To check that the kernel is sufficiently similar, compare the "dmesg" output | ||||
|    both before and after flashing the new firmware.  The kernel version string | ||||
|    should be similar, but should have a different build date and user@host | ||||
|    indicator.  The kernel binary itself is not easily accessible from an SSH | ||||
|    login, but may be retrievable using the U-Boot console (the start address of | ||||
|    the kernel in flash appears to be 0x9F000000, based on the u-boot\verb0_0reflash | ||||
|    instructions).  We were not able to verify this, due to the serial connection | ||||
|    issues (see above section on U-Boot installation). | ||||
| 
 | ||||
| \section{Minor Infractions} | ||||
| 
 | ||||
| As mentioned above, there were a few minor infractions.  These made it slightly | ||||
| difficult to complete the build and installation without additional context, but | ||||
| did not make the build impossible to complete without more information, such as | ||||
| missing source code for kernel modules or depending on a specific cross-compiler | ||||
| but not mentioning which one or, better yet, including its source code, which | ||||
| are both more problematic infractions.  These minor infractions were: | ||||
| 
 | ||||
| % FIXME: clarify seriousness of no install instructions; lack of clarity in | ||||
| % which version to install could be more problematic | ||||
| 
 | ||||
| * Not mentioning how to extract the source tarball and then where to run the | ||||
|   "make" command. | ||||
| * Not mentioning how to install the kernel and root filesystem on the device; | ||||
|   this is the biggest of these 3 issues but a bit less troublesome than it would | ||||
|   otherwise have been since the web-based firmware update process is well-known. | ||||
| * Using pre-built toolchain binaries that don't work on all systems instead of | ||||
|   the ones that are built in a separate step, but not moved to the right place. | ||||
|   We were able to build corresponding toolchain binaries from source (though | ||||
|   for a slightly different target) so this is not a severe toolchain violation | ||||
|   of the type we normally find (where toolchain binaries are provided without | ||||
|   source).  However, including instructions to use the built toolchain binaries | ||||
|   instead would be best, or alternatively specifying the distribution on which | ||||
|   the toolchain binaries must be run (to avoid being unable to run them as we | ||||
|   were). | ||||
| 
 | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| \chapter{Bortez: Modified GCC SDK} | ||||
|  | @ -799,307 +1098,7 @@ Linux.  A decade later, this situation remains largely unresolved. | |||
| 
 | ||||
| \end{enumerate} | ||||
| 
 | ||||
| 
 | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| % FIXME: make this section properly TeX-formatted | ||||
| \chapter{ThinkPenguin Wireless Router: A study in Excellent CCS} | ||||
| 
 | ||||
| This case study does a step-by-step build and installation analysis of  one | ||||
| of the best Complete, Corresponding Source (CCS) releases we've seen.  The | ||||
| CSS release studied here was provided for the binary distribution of a | ||||
| physical product by ThinkPenguin.  The product is the model | ||||
| ``TPE-NWIFIROUTER'', a wireless router. | ||||
| 
 | ||||
| The method of | ||||
| distribution (complete source accompanying the product) and the way the source | ||||
| was laid out provide very good examples of how to make things easier for both | ||||
| the distributor and the purchaser of the hardware containing GPLed components. | ||||
| 
 | ||||
| \section{Root Filesystem and Kernel Compilation} | ||||
| 
 | ||||
| * We found a CD included in the box that the ThinkPenguin TPE-NWIFIROUTER | ||||
|   shipped in, labelled "libreCMC v1.2.1 source code".  On the CD, there was a | ||||
|   README file at the top level, which mentioned that to build the software, one | ||||
|   needed a GNU/Linux system as well as a list of approximately 10 packages. | ||||
|   These sorts of plain text instructions are helpful because we know what kind | ||||
|   of system we are expected to use, and what commands we should run on it.  Such | ||||
|   instructions are not strictly required, as an obviously-named shell script may | ||||
|   suffice, but they are helpful in clarifying any ambiguities that may arise. | ||||
| ** Since it appears that this source release will build on a wide range of | ||||
|    distributions, it was fine that no specific distribution was specified. | ||||
|    However, most source releases we see will only build on a very specific | ||||
|    distribution, due to a variety of assumptions made about the build | ||||
|    environment.  While such a situation is not ideal in the general sense, it is | ||||
|    fine to specify a particular distribution that must be use to build the | ||||
|    source release (such as "Debian 7 amd64"), from a compliance perspective. | ||||
|    As an example, we noticed such an assumption later on in this source release, | ||||
|    but it would be easy to correct in the instructions in this situation (see | ||||
|    "`GLIBC\verb0_02.14' not found" below). | ||||
| 
 | ||||
| % FIXME: Spend some  time here (admittedly a digression: maybe refer to | ||||
| % another section later?) about how it's ok to specify a specific build | ||||
| % environment. | ||||
| % FIXME(dg): Hopefully the above will suffice.  I can expand more/differently if | ||||
| % such is desired. | ||||
| 
 | ||||
| * The actual building of the source code was completed in the following way: | ||||
| ** Since the instructions didn't mention a specific distro to use, we ran the | ||||
|    build on an amd64 Debian 6 machine we had.  The only distro requirement was: | ||||
| 
 | ||||
| To build your own firmware you need to have access to a GNU/Linux system | ||||
| (case-sensitive filesystem required). | ||||
| 
 | ||||
| ** The README mentioned that: | ||||
| 
 | ||||
| "In order to build firmware images for your router,the | ||||
| following needs to be installed : | ||||
| 
 | ||||
| gcc, binutils, bzip2, flex, python, perl, make, find, | ||||
| grep, diff, unzip, gawk, getopt, libz-dev and libc headers." | ||||
| 
 | ||||
|    So we ran "dpkg --list" and confirmed that each package was installed (this | ||||
|    is indicated by a leading "ii" on the line containing the package).  Other | ||||
|    GNU/Linux distributions may have other ways of determing which packages are | ||||
|    installed. | ||||
| ** We then extracted the LibreCMC tarball by running | ||||
|    "tar --posix -jxpf /media/libreCMC\verb0_0v1\verb0_02\verb0_01\verb0_0SRC/librecmc-v1.2.1.tar.bz2".  The | ||||
|    CD did contain another tarball (librecmc-u-boot.tar.bz2), but there appeared | ||||
|    to be separate instructions for that (in the u-boot\verb0_0reflash text file in the | ||||
|    same directory).  Having the README be more explicit about this would be nice | ||||
|    but did not ultimately prevent us from determing the proper steps to execute. | ||||
| ** The README mentioned the following optional step, which we skipped because | ||||
|    we did not need to modify the configuration for our initial build: | ||||
| 
 | ||||
| Please use "make menuconfig" to configure your appreciated | ||||
| configuration for the toolchain and firmware. Please note that | ||||
| the default configuration is what was used to build the firmware | ||||
| image for your router. It is advised that you use this configuration. | ||||
| 
 | ||||
| ** The next instruction was 'Simply running "make" will build your firmware.' | ||||
|    So we entered the "librecmc" directory that had been created from the above | ||||
|    "tar" command and then ran "make".  The build took about 40 minutes to run on | ||||
|    our system.  The command used and output from running it are available here: | ||||
| 
 | ||||
|     enforcement-case-studies\verb0_0log-output/thinkpenguin\verb0_0librecmc-complete.log | ||||
| 
 | ||||
| % FIXME: Above, I'd like to see more ``walk through'' of the step by step | ||||
| % instructions.  The text is a bit terse: could be expanded to talk more. | ||||
| % FIXME(dg): Hopefully the above will suffice.  I can expand more/differently if | ||||
| % such is desired. | ||||
| 
 | ||||
| * It was helpful to know that we could use "make menuconfig" for configuration | ||||
|   changes, as being able to modify the source is an important part of the GPL's | ||||
|   requirements.  Adding instructions like these shows that the distributor is | ||||
|   aware of and interested in promoting the spirit of the GPL, by making it | ||||
|   easier to modify the source than may be strictly required by the GPL's text. | ||||
| 
 | ||||
| % FIXME: We should somewhere (perhaps on each step we discuss) talk about | ||||
| % what often goes wrong on those steps, and why this is right.  As written | ||||
| % now, there is no driving home of the fact that it is uncommon that things | ||||
| % are so smooth. :) | ||||
| % FIXME(dg): Hopefully the below will suffice.  I can expand more/differently if | ||||
| % such is desired.  (I presume the above comment relates to the below text.) | ||||
|    | ||||
| * The "make" step completed successfully on our system and resulted in several | ||||
|   files being generated in the bin/ar71xx directory, namely firmware images. | ||||
| ** This step is normally where we run into the greatest number of build issues | ||||
|    (and thus compliance problems).  In many cases, the "make" step will fail due | ||||
|    to a missing package or because toolchain paths are not setup correctly.  As | ||||
|    a result, it is important to test the provided instructions on a clean system | ||||
|    before distributing the binaries and corresponding source.  Listing the | ||||
|    specific GNU/Linux distribution and any non-default packages required for the | ||||
|    build (ie. those installed before testing the instructions) in the build | ||||
|    instructions makes it easier for the end user to successfully build the | ||||
|    source release. | ||||
| 
 | ||||
| * There appeared to be several filesystem and kernel images, for different | ||||
|   hardware versions.  It was unclear which one to install on the particular | ||||
|   device we received or how to install it, both of which should have been | ||||
|   mentioned in the README. | ||||
| 
 | ||||
| % FIXME: Below, we probably want to talk to them to add this, and also, be a | ||||
| % bit more expansive. | ||||
|    | ||||
| * The above installation issue is mitigated by the availability of a web UI in | ||||
|   the product that performs firmware image installation.  It would be best if | ||||
|   instructions like those at http://librecmc.org/librecmc/wiki?name=Tp+MR3020 | ||||
|   were included in the README, as the user cannot be expected to infer that or | ||||
|   to find such a link. | ||||
| 
 | ||||
| \section{Root Filesystem and Kernel Installation} | ||||
| 
 | ||||
| As mentioned above, the specific steps for installing an updated firmware image | ||||
| were not provided, but we found that the firmware update method available in the | ||||
| web interface worked fine.  In particular, we went to http://192.168.10.1/ in | ||||
| our browser, then logged in and chose System -> Backup / Flash Firmware.  From | ||||
| there, we went to the "Flash new firmware image" section and selected the | ||||
| librecmc-ar71xx-generic-tl-wr841n-v8-squashfs-sysupgrade.bin image in the | ||||
| bin/ar71xx directory mentioned above.  We chose the "v8" image because we found | ||||
| our router said "v8.2" on the bottom and "sysupgrade" because we were doing a | ||||
| firmware upgrade rather than a fresh install. | ||||
| 
 | ||||
| When we clicked "Flash image...", we were prompted to confirm the MD5 hash of | ||||
| the image to flash and then clicked "Proceed" to flash the image.  The process | ||||
| took about one minute, at which point we were back at the web UI login screen. | ||||
| We logged in and found that the Kernel Log section showed we were running the | ||||
| new kernel. | ||||
| 
 | ||||
| We then logged in via SSH again and ran "busybox", which printed the new version | ||||
| string, showing it was using our newly-compiled version (given the date). | ||||
| 
 | ||||
| \section{U-Boot Compilation} | ||||
| 
 | ||||
| * As mentioned above, we also found a "u-boot\verb0_0reflash" file at the top level of | ||||
|   the included source CD.  We followed the instructions for compiling U-Boot, | ||||
|   which were fairly straight-forward.  One modification would be to mention that | ||||
|   "\$U-BOOT\verb0_0SRC" referred to the extracted source directory, which was implied, | ||||
|   but should have been explicit. | ||||
| * Additionally, we noticed that the included toolchain binaries, which were used | ||||
|   by the U-Boot compilation process by default, did not run on our system.  In | ||||
|   particular, we received this error: | ||||
| 
 | ||||
| mips-librecmc-linux-uclibc-gcc.bin: /lib/libc.so.6: version `GLIBC`\verb0_02.14' not found (required by mips-librecmc-linux-uclibc-gcc.bin) | ||||
| 
 | ||||
|   The complete log output (including the command used to run it) is here: | ||||
| 
 | ||||
|      enforcement-case-studies\verb0_0log-output/thinkpenguin\verb0_0u-boot-build\verb0_0fail.log | ||||
| 
 | ||||
| * We found that by removing toolchain/bin and symlinking the toolchain built for | ||||
|   the filesystem/kernel above in its place, we were able to complete the U-Boot | ||||
|   build.  Specifically, we symlinked toolchain/bin to: | ||||
| 
 | ||||
|   ../../staging\verb0_0dir/toolchain-mips\verb0_034kc\verb0_0gcc-4.6-linaro\verb0_0uClibc-0.9.33.2/bin | ||||
| 
 | ||||
|   Output from the symlink operation can be found here: | ||||
| 
 | ||||
|      enforcement-case-studies\verb0_0log-output/thinkpenguin\verb0_0u-boot-create\verb0_0symlink.log | ||||
| 
 | ||||
| * Ideally the pre-built toolchain binaries should not be included and a symlink | ||||
|   as mentioned above should be created by default, with a mention that the | ||||
|   U-Boot build depends on the previous build for its toolchain. | ||||
| * After compilation completed successfully, we found a new U-Boot image in the | ||||
|   bin directory.  The instructions explained how to install it on the device. | ||||
|   Output from the successful build (after the symlink was created) is here: | ||||
| 
 | ||||
|      enforcement-case-studies\verb0_0log-output/thinkpenguin\verb0_0u-boot-finish\verb0_0build.log | ||||
| 
 | ||||
| \section{U-Boot Installation} | ||||
| 
 | ||||
| We obtained a serial cable along with our router, in order to complete the | ||||
| U-Boot installation per the instructions in u-boot\verb0_0reflash.  However, we were | ||||
| only able to read data from the serial port; we were unable to interrupt the | ||||
| boot process or access the U-Boot console to complete the U-Boot re-flash.  Here | ||||
| are the steps we tried: | ||||
| 
 | ||||
| * We found the serial cable included was a USB serial adapter that had a male | ||||
|   USB type A connector on one end and 4 female jumper wires at the other end. | ||||
|   These female jumper wires were red, black, white, and green. | ||||
| * The instructions did not specify how to connect these wires, but we were able | ||||
|   to determine this in part using the "v8.4" image (close to our "v8.2" router) | ||||
|   at \url{http://wiki.openwrt.org/toh/tp-link/tl-wr841nd#serial.console} .  Aside from | ||||
|   power and ground (red and black), we did have to guess which of the wires was | ||||
|   RX and TX.  By experimentation we found that green was RX and white was TX. | ||||
|   When we tried the other way, we received no data to our serial console at boot | ||||
|   time. | ||||
| * We did have to use the included jumper pin gender changer with the USB serial | ||||
|   adapter, which we put through the holes on the router's mainboard and then | ||||
|   connected to the USB serial adapter.  The fit was fairly loose so it would be | ||||
|   nice if future router versions included a tighter gender changer or (ideally) | ||||
|   had the jumper pins soldered onto the board to begin with (so no gender | ||||
|   changer would be required). | ||||
| * We used 115200 8N1 as our serial console settings (with no hardware or | ||||
|   software flow control).  This was tested with both the minicom and screen | ||||
|   commands.  We found that if we connected all 4 wires on the USB serial adapter | ||||
|   that the router would start without additional power and our console would | ||||
|   receive the startup messages.  We could replicate the same behavior by | ||||
|   omitting the power cable from the USB serial adapter (red wire) and connecting | ||||
|   the main power adapter to the router instead. | ||||
| * While we did see the U-Boot and kernel boot logs in our serial console, we | ||||
|   were unable to interrupt the boot process as u-boot\verb0_0reflash indicated we | ||||
|   should.  We suspect this is a misconfiguration of our serial console, but it's | ||||
|   unclear exactly how it is misconfigured, as we were able to receive data fine | ||||
|   (we just couldn't send data to the router). | ||||
| * As a result, we were unable to complete the U-Boot installation test.  We did | ||||
|   appreciate that installation instructions were included, though these | ||||
|   instructions should be updated to include more specifics about connecting the | ||||
|   serial cable.  Since ThinkPenguin does have the option to ship a serial | ||||
|   adapter with the router, it would be helpful if instructions specific to that | ||||
|   adapter were included, as the wiring configuration one should use was unclear. | ||||
| * Additionally, instructions for removing the router's case should be included. | ||||
|   We found that the two screws that needed removal to open the case were hidden | ||||
|   underneath rubber feet on the case.  Indicating which feet need removal to | ||||
|   unscrew the case would be helpful.  The instructions should also note that the | ||||
|   case needs to be carefully separated once the screws are removed; it | ||||
|   effectively snaps apart, but care must be taken to avoid breaking the plastic | ||||
|   fasteners that keep the case together after the screws are removed. | ||||
| 
 | ||||
| \section{Firmware Comparison} | ||||
| 
 | ||||
| To ensure that the CCS did indeed correspond to the firmware that was shipped on | ||||
| the router, we compared the firmware image that we built using the above steps | ||||
| with the filesystem we found on the device itself.  The comparison steps we used | ||||
| were: | ||||
| 
 | ||||
| * Extract the filesystem from the image we built by running find-firmware.pl | ||||
|   from https://gitorious.org/gpl-compliance-tools/gpl-compliance-scripts on | ||||
|   librecmc-ar71xx-generic-tl-wr841n-v8-squashfs-factory.bin from the bin/ar71xx | ||||
|   directory mentioned above (we noticed that our router said "Ver:8.2" on the | ||||
|   bottom).  Then run squashfs4.2/squashfs-tools/bat-unsquashfs42 from | ||||
|   bat-extratools (at http://www.binaryanalysis.org/en/content/show/download ) | ||||
|   on the resulting morx0.squash and use the filesystem in the new squashfs-root | ||||
|   directory for comparison. | ||||
| * Login to the web interface (at http://192.168.10.1/ ) from a computer that is | ||||
|   connected to the router. | ||||
| * Set a password using the provided link at the top (the UI warns that no | ||||
|   password is set and asks the user to change it). | ||||
| * Login to the router via SSH, using the root user and the password we just set. | ||||
| * Compare representative directory listings and binaries to ensure the set of | ||||
|   included files (on the router) is similar to those found in the firmware image | ||||
|   we created (whose contents are now in the local squashfs-root directory).  In | ||||
|   particular, we did the following comparisons: | ||||
| ** List the /bin folder ("ls -l /bin") and confirm the list of files is the same | ||||
|    and that the file sizes are similar. | ||||
| ** Check the "strings" output of /bin/busybox to confirm it was similar in both | ||||
|    places (similar number of lines and content of lines).  One cannot directly | ||||
|    compare the binaries because the slight compilation variations will cause | ||||
|    some bits to be different. | ||||
| ** Do the above two steps for /lib/modules, /usr/bin, and other directories with | ||||
|    a significant number of binaries. | ||||
| ** To check that the kernel is sufficiently similar, compare the "dmesg" output | ||||
|    both before and after flashing the new firmware.  The kernel version string | ||||
|    should be similar, but should have a different build date and user@host | ||||
|    indicator.  The kernel binary itself is not easily accessible from an SSH | ||||
|    login, but may be retrievable using the U-Boot console (the start address of | ||||
|    the kernel in flash appears to be 0x9F000000, based on the u-boot\verb0_0reflash | ||||
|    instructions).  We were not able to verify this, due to the serial connection | ||||
|    issues (see above section on U-Boot installation). | ||||
| 
 | ||||
| \section{Minor Infractions} | ||||
| 
 | ||||
| As mentioned above, there were a few minor infractions.  These made it slightly | ||||
| difficult to complete the build and installation without additional context, but | ||||
| did not make the build impossible to complete without more information, such as | ||||
| missing source code for kernel modules or depending on a specific cross-compiler | ||||
| but not mentioning which one or, better yet, including its source code, which | ||||
| are both more problematic infractions.  These minor infractions were: | ||||
| 
 | ||||
| % FIXME: clarify seriousness of no install instructions; lack of clarity in | ||||
| % which version to install could be more problematic | ||||
| 
 | ||||
| * Not mentioning how to extract the source tarball and then where to run the | ||||
|   "make" command. | ||||
| * Not mentioning how to install the kernel and root filesystem on the device; | ||||
|   this is the biggest of these 3 issues but a bit less troublesome than it would | ||||
|   otherwise have been since the web-based firmware update process is well-known. | ||||
| * Using pre-built toolchain binaries that don't work on all systems instead of | ||||
|   the ones that are built in a separate step, but not moved to the right place. | ||||
|   We were able to build corresponding toolchain binaries from source (though | ||||
|   for a slightly different target) so this is not a severe toolchain violation | ||||
|   of the type we normally find (where toolchain binaries are provided without | ||||
|   source).  However, including instructions to use the built toolchain binaries | ||||
|   instead would be best, or alternatively specifying the distribution on which | ||||
|   the toolchain binaries must be run (to avoid being unable to run them as we | ||||
|   were). | ||||
| 
 | ||||
| 
 | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Bradley M. Kuhn
						Bradley M. Kuhn