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
|
requests, and in this course, we examine four specific examples of such
|
||||||
compliance work.
|
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}
|
\chapter{Bortez: Modified GCC SDK}
|
||||||
|
@ -799,307 +1098,7 @@ Linux. A decade later, this situation remains largely unresolved.
|
||||||
|
|
||||||
\end{enumerate}
|
\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…
Reference in a new issue