FIXME: Most of the instructions below seem to apply only to ancient boards running U-Boot.Motivation[If you are familiar with/sold on network-based development you can skip this introduction.]Development with a target device, where software is built on a separate host, is quite different from host-based development. Perhaps the biggest problem is that the host and target have different filesystems. The host filesystem is close to you, easy to interact with, large, fast and always available. The target filesystem is typically inaccessible from your host, has poor tools, is small, pretty slow and only exists when the target is running. Common problems are:
These problems are worse when you want to have a lab full of targets all doing similar things. In this case each board must be reconfigured using an SD card and manual intervention when a kernel update is required, or a log file must be pulled off. In fact, anything which exists on the target device is something that might be out of date, something to check, or something that will make that target different in undesirable ways. In short it is desirable to keep as little as possible on the target device. If a network is available at all stages of the boot process, you can use that instead of the filesystem. At the minimum you need to identify the target, so it needs a name and perhaps a serial number. Everything else can be loaded from an attached network. Common objections to using a network, compared to an SD card say, are:
Chromium OS Approach(ARM only, for now).Our approach to network-based development is:
The remainder of this page shows how to set this up. U-Boot on the boardChromium OS has several variants of U-Boot for each board, one of which is the developer variant. The developer variant has a number of additional features useful to devs: network support, an expanded command set and a saved environment.First, make sure that you have flashed the developer U-Boot onto your board. For more information see the U-Boot page. Supported USB Ethernet Adapters / USB Ethernet DonglesOnly the ASIX AX88772 chip is supported at present. The following supported adapters are shown as {vendor, device}. Typelsusb , on a machine running Linux, with the adapter attached to see the vendor and device numbers for your adapter. { 0x05ac, 0x1402 }, /* Apple USB Ethernet Adapter */ { 0x07d1, 0x3c05 }, /* D-Link DUB-E100 H/W Ver B1 */ { 0x0b95, 0x772a }, /* Cables-to-Go USB Ethernet Adapter */ TODO(dianders): This didn't work for me. { 0x0b95, 0x7720 }, /* Trendnet TU2-ET100 V3.0R */ { 0x0b95, 0x1720 }, /* SMC */ { 0x0db0, 0xa877 }, /* MSI - ASIX 88772a */ { 0x13b1, 0x0018 }, /* Linksys 200M v2.1 */ { 0x1557, 0x7720 }, /* 0Q0 cable ethernet */ { 0x2001, 0x3c05 }, /* DLink DUB-E100 H/W Ver B1 Alternate */ U-Boot Environment VariablesWhen you start the developer U-Boot for the first time it will likely complain that the environment is not present, and give you a default environment. Typeprintenv to see what it defines.To set your board up for full network booting you need to set the following. Replace the IP addresses in the following with the address of your server. In fact, typical U-Boot flow is to use serverip for all the server addresses, and have this obtained automatically from the DHCP server. However in many corporate network environments this is difficult.Note: It is a great idea if your DHCP server can give you the same IP address each time. It does this by looking at the MAC address on your board / Ethernet adapter. Note that you should replace yourUsernameHere with the username you'll be using on your host machine and yourSerialNumberHere with anything you want. You should also change the IP address to be the IP addresses of your servers.setenv serverip 172.22.73.60 setenv tftpserverip 172.22.73.60 setenv nfsserverip 172.22.73.60 setenv board tegra2_seaboardsetenv serial# yourSerialNumberHere setenv user yourUsernameHere Other variables are set automatically by the boot scripts: rootpath=/export/nfsroot-${user}-${board}-${serial#} There are two paths that your server must provide. The first is the path to your kernel on your tftp server, and the second is the path to your root disk on your NFS server. By adding the username, board and serial number it makes it possible for a team to share a single TFTP/NFS server. By default the IP address is obtained using DHCP. If you don't have a DHCP server you can set the environment variables directly. You will need to create your own boot flow which skips bootp. gatewayip=172.22.73.1 netmask=255.255.255.0 ipaddr=172.22.73.81 U-Boot Boot FlowU-Boot starts by running an environment variable calledbootcmd . This starts up USB then tries various ways of obtaining a kernel:
To adjust the boot flow you should create your own boot command. For example you might create a method that loads a kernel from partition 2 of the USB stick, so replacing nfskey_boot ,. Then change the bootcmd so it only runs your flow (NOTE: you may need to paste it a little bit at a time):setenv mynfs_setup 'setenv rootpath /export/nfsroot-${user}-${board}-${serial#}; run regen_net_bootargs' setenv mynfs_boot 'run keynfs_setup; ext2load usb 0:2 ${loadaddr} uImage; bootm ${loadaddr}' setenv bootcmd run mynfs_boot saveenv Setting up a DHCP serverThe DHCP server provides IP addresses to targets on your network. If you have a DHCP server already, skip to the end of this section to test it. Otherwise you will need to set one up. This is a very brief guide.sudo aptitude install dhcp3-server Edit /etc/dhcp3/dhcpd.conf and add details about your subnet, including the range of IP addresses you want to give out and any fixed IP addresses you want to allocate for your targets: subnet 192.168.4.0 netmask 255.255.255.0 { range 192.168.4.20 192.168.4.50; option routers 192.168.4.1; } host seaboard { hardware ethernet 00:23:7d:09:80:0e; fixed-address seboard0; } (you may want to put seaboard0 in your /etc/hosts file in this example, or you can use a numeric address)Then start up the server: /etc/init.d/dhcp3-server restart If there are no errors ( tail /var/log/syslog ) you should be in business.Testing your DHCP serverAt this stage you should be able to boot your target and see it get a valid IP address:CrOS> usb start (Re)start USB... USB: Tegra ehci init hccr c5008100 and hcor c5008140 hc_length 64 Register 10011 NbrPorts 1 USB EHCI 1.00 scanning bus for devices... 5 USB Device(s) found scanning bus for storage devices... 1 Storage Device(s) found scanning bus for ethernet devices... 1 Ethernet Device(s) found CrOS> bootp Waiting for Ethernet connection... done. BOOTP broadcast 1 DHCP client bound to address 172.22.73.81 CrOS> Setting up a TFTP serverThe TFTP server will send a kernel to U-Boot when it asks. If you have one already skip to the end of this section to test it.sudo aptitude install tftpd-hpa Then edit /etc/default/tftpd-hpa like this replacing yourUsernameHere with your own username (echo $USER ):TFTP_USERNAME="yourUsernameHere" TFTP_DIRECTORY="/tftpboot" TFTP_ADDRESS="0.0.0.0:69" TFTP_OPTIONS="-v" Notes:
Suggestions for good workflows that fix some of the above would be appreciated. Now prepare it. We want a symlink from the /tftpboot directory to you kernel, so the target can easily read it. Replace the filename with your user, board and serial. NOTE: this assumes that you've got your chromiumos source code in /home/$USER/chromiumos :cd /tftpboot sudo ln -s /home/$USER/chromiumos/chroot/build/tegra2_seaboard/boot/vmlinux.uimg uImage-$USER-tegra2_seaboard- yourSerialNumberHeresudo restart tftpd-hpa Testing your TFTP serverEnsure that you have an IP address (as shown in the DHCP section above). Then this should read in the kernel (assuming you've built it):tftpboot ${loadaddr} ${tftpserverip}:/tftpboot/uImage-${user}-${board}-${serial#} You'll see this output if things are working well: Waiting for Ethernet connection... done. yourSerialNumberHere'.Load address: 0x40c000 Loading: ################################################################# ################################################################# ################################################################# ############################################### done Bytes transferred = 3545596 (3619fc hex) If you have got this far, congratulations! You are about half way there: the target is reading a kernel directly from your machine and is ready to boot it. Now we need to get the root disk organized. NFS RootNFS root is a simple way to keep your target's root disk be kept on the network.Advantages:
Disadvantages:
You can find information about setting up NFS root here. These instructions replicate much of that, and generally follow the same pattern but are more specific to Chromium OS. Note that you can use NFSv3 instead but here we will use NFSv4 as it has additional features. The steps you need to take are:
Setting up an NFS serverFirst, install the NFS server package (these instructions for Ubuntu 10.04 Lucid). This enables the NFS server built into your kernel. When it starts you may notice that a number of new modules have been loaded into your kernel (nfsd, exportfs, lockd, etc.)sudo aptitude install nfs-kernel-server The server needs to know which directories you want to 'export' for clients. This is specified in the /etc/exports file. Edit this (sudo nano /etc/exports or similar) to look something like this (changing IP subnets as appropriate):/export 172.16.0.0/16(rw,fsid=0,no_subtree_check,async) /export/nfsroot-yourUsernameHere-tegra2_seaboard- yourSerialNumberHere 172.16.0.0/16(rw,nohide,no_subtree_check,async,no_root_squash)The first entry sets the base of the NFS exports. Every directory which is exported must be accessible from within /export .
The second entry is the nfsroot directory which will contain your root
filesystem. This is the directory that the client will see when it
mounts the NFS root. The IP address should be changed to match your
local setup - it sets the range of IP addresses which are allowed to access this mount on the server. For example it might be 192.168.1.0/24 .A number of options are provided, briefly:
/export/nfsroot . Rather than just copy it there, we will use a 'bind mount' to paste the true location onto /export/nfsroot . First we need to unpack a suitable image (see the build instructions for how to build an image).Let's assume that you have your Chromium trunk directory as ~/cosarm and you are using a tegra2_seaboard build:# go to the directory with the latest build # mount it into /tmp/m ~/cosarm/src/scripts/mount_gpt_image.sh -f . -i chromiumos_test_image.bin
# unmount the image from /tmp/m ~/cosarm/src/scripts/mount_gpt_image.sh -u
This will put a full copy of the build image root disc into ~/cosarm/src/build/images/tegra2_seaboard/latest/nfsroot . Now we need to make it appear in /export/nfsroot . Edit your /etc/fstab file with the full path:/full/path/to/cosarm/src/build/images/tegra2_seaboard/latest/nfsroot /export/nfsroot-yourUsernameHere-tegra2_seaboard-yourSerialNumberHere none bind 0 0 Note this must appear all on one line and you can use tabs or spaces between fields. See man fstab for more information.You will need to create an /export/nfsroot directory: $ sudo mkdir -p /export/nfsroot -yourUsernameHere-tegra2_seaboard- yourSerialNumberHere This
will be activated automatically when your server reboots, but since it
is already running, ask it to mount this now. After the mount you will
see that the root filesystem has appeared at /export/nfsroot as desired.$ sudo mount /export/nfsroot -yourUsernameHere-tegra2_seaboard- yourSerialNumberHere$ ls /export/nfsroot -yourUsernameHere-tegra2_seaboard- yourSerialNumberHere/ bin dev home lost+found mnt postinst root share tmp usr boot etc lib media opt proc sbin sys u-boot var $ Check that your /etc/idmapd.conf
is correct. You can leave the domain as is if you like. If you change
it, be careful that the same domain is used on the client side (not
relevant for NFS root though). This file sets up mapping of user and
group names between the client and server and is a key benefit of NFSv4
over NFSv3.[General] Verbosity = 0 Pipefs-Directory = /var/lib/nfs/rpc_pipefs Domain = local.domain.edu [Mapping] Nobody-User = nobody Nobody-Group = nogroup Also check your portmap settings. If this is wrong then the boot will fail with a message like 'VFS: Unable to mount root fs via NFS, trying floppy.'. The settings are in /etc/defaults/portmap . Make sure it is set to provide the service to other machines. If your options are set to "-i 127.0.0.1" then it will only work locally (not a useful server!). Change it to OPTIONS="" and then 'restart portmap'. You can test this:$ rpcinfo -p 172.22.73.60 # use hostname or IP address of your NFS server rpcinfo: can't contact portmapper: RPC: Remote system error - Connection refused If it is working you will see something like: $ rpcinfo -p 172.22.73.60 |grep nfs 100003 2 udp 2049 nfs 100003 3 udp 2049 nfs 100003 4 udp 2049 nfs 100003 2 tcp 2049 nfs 100003 3 tcp 2049 nfs 100003 4 tcp 2049 nfs Restart the NFS kernel server if you are superstitious: $ sudo /etc/init.d/nfs-kernel-server restart * Stopping NFS kernel daemon [ OK ] * Unexporting directories for NFS kernel daemon... [ OK ] * Exporting directories for NFS kernel daemon... [ OK ] * Starting NFS kernel daemon [ OK ] Test your nfs server setup. This example just mounts the nfsroot on the same machine, but it is useful to do this from another machine is possible (if you can, use your server host name instead of localhost). $ sudo mkdir -p /tmp/nfs4 $ sudo mount -t nfs4 localhost:/nfsroot /tmp/nfs4 $ ls /tmp/nfs4 bin boot build dev etc home lib lost+found media mnt opt postinst proc root sbin share sys tmp usr var $ sudo umount /tmp/nfs4 /export/nfsroot -yourUsernameHere-tegra2_seaboard- yourSerialNumberHere/etc/init/iptables.conf file should be changed to do this. At the top, change the start on line to start on never .
If you don't do this you will likely boot to a login prompt, but then
you will see 'NFS server not responding' messages once the firewall
kicks in.Build a suitable kernelYou can build an NFS-enabled kernel for Chromium OS with something like:USE=nfs emerge-tegra2_seaboard chromeos-kernel This puts a kernel in /build/<board>/boot/vmlinux.uimg. TODO(dianders): Maybe this is what we want? USE=nfs FEATURES="noclean" cros_workon_make --board=${BOARD} --install kernel Longer ExplanationThere are quite a few options that you need to enable in the kernel to support NFS root. First you need to make sure that a suitable network driver is compiled in, and secondly you need to enable all the network filesystem options. The following list for a USB network adapter setup gives you an idea of what is required. Some of the important options are:
Note: some of the options below are required for NFS root, some for NFS mounting and some for NFS serving. chromeos/config/armel/config.flavour.chromeos-tegra2 :CONFIG_USB_NET_AX8817X=y chromeos/config/config.common.chromeos: +CONFIG_DNOTIFY=y +CONFIG_DNS_RESOLVER=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFSD=m +CONFIG_NFSD_V3=y +CONFIG_NFSD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_NFS_FS=y +CONFIG_NFS_USE_KERNEL_DNS=y +CONFIG_NFS_V3=y +CONFIG_NFS_V4=y +CONFIG_ROOT_NFS=y +CONFIG_RPCSEC_GSS_KRB5=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_USB_USBNET=y
Putting it all togetherYou are now ready to try out your new kernel. Just start up your target and type 'boot'.A partial boot trace is shown below to show the sequence of events: U-Boot 2010.09-00199-g4c814f0-dirty (Feb 14 2011 - 16:33:28) TODO: Troubleshooting? NFS CaveatsSome things to be aware of:
|
Chromium OS > How Tos and Troubleshooting >