How to get NFS mounts working in Android emulator

From Dmz-portal

Jump to: navigation, search

Contents

Summary

Build Android MIPS goldfish QEMU kernel with NFS client support turned on

This assumes you have the environment variable, ANDROID_NDK, set to the base directory for the Android NDK. I have it set to:


ANDROID_NDK=/mips/tools/mips/swpkgs/lib/android-ndk-r8b

Also, the environment variable, ANDROID, should be set to where you built Android. Lastly, you will need to know how to start and stop the Android emulator with it initially running.


Manually building and configuring the kernel

First get a copy of the kernel source from git. Be sure to use the mips-android-goldfish-2.6.29 branch. You'll need to have an account setup on the mipsia.review.mips.com to use the following git command. But, the kernel sources should available in other places:


git clone -b mips-android-goldfish-2.6.29 ssh://mipsia.review.mips.com:29418/kernel/goldfish.git

Create a directory for the kernel build called "build" to separate the kernel source from the build:


mkdir build

Next, get and decompress the current kernel configuration from your Android emulator using adb. Store the configuration file in your kernel build directory and call it .config:


$ANDROID/out/host/linux-x86/bin/adb pull /proc/config.gz build/config.gz
gunzip build/config.gz
mv build/config build/.config

Using menuconfig, configure the kernel with NFS. This should use the kernel configuration you got from the Android emulator as the base. To get into menuconfig:


cd build
make ARCH=mips CROSS_COMPILE=$ANDROID_NDK/toolchains/mipsel-linux-android-4.4.3/prebuilt/linux-x86/bin/mipsel-linux-android- O=$PWD -C ../goldfish menuconfig

Then, in menuconfig navigate to:


-> File systems
  -> Network File Systems
     -> NFS client support

and set "NFS client support" to "y". Then, go down one and set "NFS client support for NFS version 3" to "y" as well:


-> File systems
  -> Network File Systems
     -> NFS client support
        -> NFS client support for NFS version 3

Exit out of menuconfig by selecting exit until it prompts you to save your configuration. At this point save your configuration and you'll be back at a shell prompt with the new configuration in .config.


Next, rebuild the kernel. If you have multiple processors, add the -j option to make to speed up the build:


make ARCH=mips CROSS_COMPILE=$ANDROID_NDK/toolchains/mipsel-linux-android-4.4.3/prebuilt/linux-x86/bin/mipsel-linux-android- O=$PWD -C ../goldfish 

Once the kernel is built, quit out of the Android emulator and copy the kernel you built to your Android build. Note this step will overwrite the current Android emulator kernel. You may want to back it up first:


cp vmlinux $ANDROID/prebuilts/qemu-kernel/mips/kernel-qemu
cp vmlinux $ANDROID/prebuilts/qemu-kernel/mips/vmlinux-qemu

At this point you should have a kernel with the NFS client turned on. Skip to "Boot emulator with new kernel". If this doesn't work (your emulator won't boot or NFS didn't get installed), try to "Build the kernel the correct way" below.

Build the kernel the correct way

Caveat emptor. This is not how I built the kernel. So, this may not work. But, it is the correct way to do it.


Boot emulator with new kernel

Assuming you followed the manual instructions including copying the kernel to the Android build location, restart the emulator as usual and you should be in the new kernel. I start it with the command:


emulator -shell -show-kernel -no-window -dns-server 192.168.36.50,192.168.37.50

If you built the kernel "the correct way" or didn't want to overwrite the existing Android QEMU kernel, you can run the emulator with the -kernel option and point at your built kernel that way:


emulator -shell -show-kernel -no-window -dns-server 192.168.36.50,192.168.37.50 -kernel $PWD/vmlinux

Download statically built MIPS busybox binary from Debian site

First download the Debian .deb package with wget or any other HTTP download tool like your web browser:


wget 'http://http.us.debian.org/debian/pool/main/b/busybox/busybox-static_1.20.0-6_mipsel.deb'

What you downloaded is a .deb package which you're not going to install on your machine. Instead you're going to extract the busybox binary from it. A .deb file is just an "ar" archive with two tar files and a file called "debian-binary" in it. This command extracts the tar file with the busybox binary in it from the "ar" archive. Then, extracts the busybox binary from the tar file and writes it to a file called busybox in the current directory:


ar p busybox-static_1.20.0-6_mipsel.deb data.tar.gz | tar xzf - -O ./bin/busybox > busybox

Restart the Android emulator if you haven't. Then, copy busybox to the /data directory with adb:


$ANDROID/out/host/linux-x86/bin/adb push busybox /data

Mount NFS directory

At this point you should be able to mount an NFS directory if the server is configured to allow insecure NFS mounts. An insecure NFS mount is one that uses ports greater than 1024 for NFS. Most NFS servers are configured to not allow this.


Log on to the emulator and switch to root if you're not:


$ANDROID/out/host/linux-x86/bin/adb shell
su

Re-mount the root filesystem read/write:


mount -o remount,rw /

Make a directory to mount the NFS server:


mkdir -p /mnt/foo

You can check if NFS is configured in your kernel with the command:


/data/busybox zcat /proc/config.gz | /data/busybox grep NFS_FS=y

You should see "CONFIG_NFS_FS=y" returned.


Make a directory to mount your NFS server. For example, /mnt/foo:


mkdir /mnt/foo

Then, mount the NFS server. In the following command, SERVER should be the IP address of the NFS server and PATH_TO_EXPORT_DIRECTORY is the directory on the NFS server being exported. (N.B. Setting SERVER and PATH_TO_EXPORT_DIRECTORY to the correct values in shell variables and pasting the below command doesn't seem to work in the Android emulator shell)


/data/busybox mount -o nolock,rw,hard,intr,vers=3 -t nfs $SERVER:$PATH_TO_EXPORT_DIRECTORY /mnt/foo

If you received no errors from the above command, you should have your exported directory mounted on the emulator. If you don't verify that your NFS server is configured correctly with insecure in the options.


Configuring the NFS server

The NFS server must be to be configured to allow insecure ports. TCP and UDP ports less that 1024 are considered "secure" and can only be opened by root. Since the emulator isn't running as root, it can't open ports less that 1024. Therefore, the ports opened by the NFS client in the Android emulator will get remapped to insecure ports by the emulator. The NFS server needs to be configured to allow this. This can be done by adding insecure to the options for your export.


Your NFS server is configured in the /etc/exports file. If you're exporting a directory called /export for all of MIPS, then you would have a line like the following in /etc/exports


/export 192.168.0.0/16(rw,no_subtree_check,insecure)

Note the insecure in the list of options. Be sure to run exportfs -r as root if you change your /etc/exports file.

If you're trying to use an NFS server like the NetApp that you're not managing, then it will not have the insecure option by default and so will not allow you to mount the directory on the Andorid emulator. It is unlikey MIPS IT will change the options on the NetApp to allow insecure ports.

Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox