The documentation for L4T recommends this page for creating a custom ubuntu rootfs, which describes using rootstock. It seems that the rootstock tool is deprecated. We have found that using multistrap is a relatively easy alternative that works.
Here is the process we are using to create a rootfs using multistrap. We create the rootfs on an sdcard, move it to an existing devkit to chroot in and run dpkg --configure. Then move the sdcard back to the host system to tar-it up and deploy.
Note that multistrap distributed with ubuntu 14.04 is broken. The fix is simple and is in comment #6. The patch is at the bottom of this post.
On the host system:
# Mount an sdcard (already formatted with something like ext2 or ext4)
sudo mkdir /mnt/sdcard
sudo mount /dev/sdaX /mnt/sdcard
# Run multistrap to generate the rootfs
sudo multistrap --file /path/to/multistrap.conf
# Tweak the filesystem to assist a few package installs
# Create a symlink for insserv
sudo ln -s ../usr/lib/insserv/insserv /mnt/sdcard/sbin/insserv
# Create a symlink for awk
sudo ln -s mawk /mnt/sdcard/usr/bin/awk
# Unmount and eject the sdcard
sudo umount /mnt/sdcard
On an existing tx1 devkit
# Insert and mount the sdcard
sudo mkdir /mnt/sdcard
sudo mount /dev/mmcblk1p1 /mnt/sdcard
# Copy a passwd and group file onto the filesystem so we don't get weird errors
# and warnings. You don't really need this step, and you probably want to
# strip down the passwd and group file to suit your needs.
# NOTE: The name of the file is 'passwd'. There seems to be a forum bug that
# prevents this post if I use 'passwd' in the line below:
sudo cp /etc/passw /mnt/sdcard/etc/
sudo cp /etc/group /mnt/sdcard/etc/
# If you are installing java, you'll need /proc mounted inside the chroot.
sudo mount -t proc /proc /mnt/sdcard/proc
# Configure packages. Note the little hack to make dash happy.
sudo chroot /mnt/sdcard /var/lib/dpkg/info/dash.preinst install
sudo chroot /mnt/sdcard dpkg --configure -a
#If you installed any packages that configure a daemon, they may have started
#inside the chroot. Find out their pid with `lsof /mnt/sdcard` and kill them.
#Unmount and eject sdcard
sudo umount /mnt/sdcard/proc
sudo umount /mnt/sdcard
Back on the host system
# Insert and mount the sdcard again. You can mount the sdcard directly to
# Linux_for_Tegra/rootfs and run flash.sh to test the root filesystem. Or you
# can create a tarfile for deployment in a fashion similar to jetpack.
sudo mount /dev/sdaX /mnt/sdcard
cd /mnt/sdcard
sudo tar cpzf /path/to/custom_rootfs.tar.gz *
Here is an example multistrap config file. Note that multistrap will not
install /etc/apt/sources.list so you’ll probably want to deploy one of those.
See the one in the sample rootfs for a sample.
[General]
# arch and directory can be specified on the command line.
arch=armhf
directory=/mnt/sdcard
# same as --tidy-up option if set to true
cleanup=true
# retain the sources outside the rootfs for distribution
# specify a directory to which all the .debs can be moved.
# or override with the --source-dir option.
# retainsources=/path/to/dep/cache
# same as --no-auth option if set to true
# keyring packages listed in each debootstrap will
# still be installed.
noauth=true
# extract all downloaded archives
unpack=true
# the order of sections is no longer important.
# debootstrap determines which repository is used to
# calculate the list of Priority: required packages
debootstrap=Trusty
# the order of sections is no longer important.
# aptsources is a list of sections to be listed
# in the /etc/apt/sources.list.d/multistrap.sources.list
# of the target.
aptsources=Trusty,TrustyUpdates
#configscript=config.sh
#setupscript=setup.sh
# Any packages installed from trusty
[Trusty]
packages=apt at acpid isc-dhcp-client nano openssh-server net-tools python rsyslog sudo tmux udev ubuntu-keyring
source=http://www.ports.ubuntu.com/ubuntu-ports
keyring=ubuntu-keyring
suite=trusty
components=main universe multiverse
omitdebsrc=true
# Any packages installed from trusty-updates
[TrustyUpdates]
packages=clang-format-3.6
source=http://www.ports.ubuntu.com/ubuntu-ports
keyring=ubuntu-keyring
suite=trusty-updates
components=main universe multiverse
omitdebsrc=true
Here is the diff to fix multistrap on ubuntu 14.04:
--- /usr/sbin/multistrap 2014-02-21 23:27:42.000000000 -0800
+++ /tmp/multistrap 2016-05-16 08:29:44.666249427 -0700
@@ -986,7 +992,7 @@
}
# reinstall set
foreach my $reinst (sort @reinstall) {
- system ("$str $env chroot $dir apt-get --reinstall -y $forceyes install $reinst");
+ system ("$str $env chroot $dir apt-get --reinstall -y install $reinst");
}
&run_native_hooks_end(sort @{$hooks{'N'}}) if (defined $hooks{'N'});
return $retval;
We’ve also patched multistrap to support the use of apt-cacher to speed up the
process of building a rootfs. We run apt-cacher on a machine in our office and
have added the ‘–apt-cacher’ command line option to multistrap.
--- /usr/sbin/multistrap 2014-02-21 23:27:42.000000000 -0800
+++ /tmp/multistrap 2016-05-16 08:29:44.666249427 -0700
@@ -36,7 +36,7 @@
$explicit_suite $allow_recommends %omitdebsrc @dsclist @sectoutput
%flatfile %important $addimportant @debconf $hookdir %hooks
$warn_count $use_shortcut @foreignarches $olddpkg $ignorenative
- %foreignpkgs $markauto $default_release /;
+ %foreignpkgs $markauto $default_release $apt_cacher /;
setlocale(LC_MESSAGES, "");
textdomain("multistrap");
@@ -74,6 +74,8 @@
$noauth++;
} elsif (/^(--dry-run|--simulate)$/) {
$dryrun++;
+ } elsif (/^(--apt-cacher)$/) {
+ $apt_cacher = shift(@ARGV);
} else {
die "$progname: "._g("Unknown option")." $_.\n";
}
@@ -343,6 +345,10 @@
$config_str .= " -o Dir::Etc::Parts=${dir}${etcdir}apt.conf.d/";
$config_str .= " -o Dir::Etc::PreferencesParts=${dir}${etcdir}preferences.d/";
$config_str .= " -o APT::Default-Release=$default_release";
+if (defined $apt_cacher) {
+ $config_str .= " -o APT::http::Proxy=${apt_cacher}";
+ $config_str .= " -o APT::https::Proxy=false";
+}
# if (not defined $preffile);
if (defined $deflist) {
$sourcesname = "sources.list.d/multistrap.sources.list";