Tag Archives: Nexus

Unlock and Root Your Nexus Using Linux

Introduction

I’ve had a lot of trouble gathering information on how to unlock and root my Nexus 6 phone (having never done anything like this before). The information on how to do this is definitely out there, but it’s all over the place in bits and pieces. So that’s where this blog comes in; I tried to group everything I learned after successfully rooting my phone and installing TWRP on it.

This diagram explains very loosely how the upgrades work; the diagram will make more sense as you read on.
Nexus Upgrade In Nutshell
Here are the topics of interest:

  • Installing the Android SDK and preparing a useful (Linux) Environment: This step is important in order to be able to interact with your device and update it via a USB cable attached to your PC. It specifically focuses on enabling the use of the adb and fastboot tools. This entire blog is useless to you if you don’t have this part set up.
  • Enabling Debug (Developer) Mode on your Android device: This step pairs with the SDK. The SDK allows your PC to communicate with your Android device while this step allows your device to be communicated with. Each device you plan on unlocking or rooting will have to have Debug Mode turned on.
  • Unlock Your Bootloader: You can not root your device unless your bootloader is unlocked. This action opens your device up to a world of tweaks and hacks. Note: this step can also can void your warranty.
  • Root Your Device: You can not root your device unless your bootloader is unlocked. This step focuses on using the excellent work of Chainfire‘s (CF-)Auto-Root boot.img and SuperSU application.
  • Upgrade Your Rooted Device: When Google puts out their new Over The Air (OTA) upgrade. You’ll notice that rooted devices won’t successfully get upgraded. Don’t worry; nothing breaks, the update simply fails. I identify the steps here how you can play along and still upgrade your rooted device.

A few other things worth sharing:

  • Fantastic Android (Root Required) Apps: Got your Android device rooted? Here are some amazing applications worth installing on it.
  • TWRP Setup: TWRP allows you to try out custom firmware. This is one of the fantastic apps i had to make a separate section for since it’s setup can be a bit confusing if you’ve never done it before.
  • Backups and Restores: Just some tips I found on creating backups and their accompanied restoring operations (in a time of need).

Getting Started

I performed all of the steps below on a Fedora 20 Linux box, but it should work on any variation of Linux (the instructions that is). Please note that these steps are specifically geared towards a Nexus 6, but I’m sure any competent person can adjust what is identified here to work with their own Android device (phone/tablet) too. 🙂

Android SDK Preparation

This step is vital for the two-way communication to your device using your PC. I did the following using Fedora 20; but the rules don’t change for most distributions.

  1. As root, make sure the proper libraries are installed and available to your environment:
    # You'll need the 32-bit version of libstdc and the JDK 
    yum install libstdc++.i686 java-1.7.0-openjdk -y
    
  2. Download the full Android SDK here (scroll to the bottom of the page>DOWNLOAD FOR OTHER PLATFORMS>SDK Tools Only). At the time I did this, the file was called: android-sdk_r24.0.2-linux.tgz.
    # Alternatively, you can fetch it this way
    # (as long as the site doesn't change their paths around):
    wget http://dl.google.com/android/android-sdk_r24.0.2-linux.tgz
    
  3. Install it’s contents into a workable directory; the following prepared my development environment placing everything in ”’~/Development/Android/SDK”’:
    mkdir -p ~/Development/Android/SDK
    # Extract contents of the SDK into our newly created directory
    # the --strip 1 eliminates the parent directory (called android-sdk-linux)
    # we just want the root of this to go into the SDK directory instead
    tar xvfz android-sdk_r24.0.2-linux.tgz -C ~/Development/Android/SDK --strip 1
    
  4. The following will allow regular users to utilize the fastboot command. Without this step, you must switch to root to utilize the command.

    cat < /etc/udev/rules.d/51-android.rules
    # Nexus 6 ID: 18d1
    SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", MODE="0666", GROUP="plugdev" 
    _EOF
    chmod 644 /etc/udev/rules.d/51-android.rules
    
  5. Now we need to add a few more tools to complete our setup. This can be done through the tools/android binary.

    # Create an environment variable to simplify the commands
    ASDK="$HOME/Development/Android/SDK"
    # Change to our development directory
    pushd $ASDK
    # Update our path
    export PATH="$PATH$ASDK/tools:$ASDK/platform-tools"
    
    # Install (the following were in the SDK r24.0.2 package)
    # they may be different in yours.
    #  1- Android SDK Platform-tools
    #  2- Android SDK Build-tools
    # 57- Android Support Library
    #
    # The following command lists all of the packages you can install:
    #    > android list sdk
    #
    # If you want to be certain you grab the right packages and
    # are using a different release, here is a cheat that will
    # fetch this information for you:
    PACKAGES=$(tools/android list sdk --extended | 
                egrep -B2 -i 'Android (Support Library|SDK Platform-tools|SDK Build-tools)' | 
                egrep '^id:' | 
                sed -e 's/[^"]+"([^"]+)"/1/g' | 
                cut -d- -f1 | tr -s '[:space:]' , | 
                sed -e 's/,+$//g')
    
    # Now install our packages! (if there are any to install)
    android update sdk -u -a -t $PACKAGES
    
    # if you get the following error, it's because you didn't install
    # libstdc++ as identified in an earlier setup:
    #   ...
    #   Stopping ADB server failed (code 127).
    #   Starting ADB server failed (code 127).
    #   Done. 3 packages installed.
    #
    # To fix this, make sure you have installed the 32-bit libstd++ (as root):
    #    yum install libstdc++.i686
    #
    # After it's installed, you can restart the adb server with the
    # following command:
    #     adb start-server
    

    Alternatively, you can just launch the tools/android binary and use the GUI to set things up. You will need to install the following (3) packages (minimally):

    1. Tools >> Android SDK Tools
    2. Tools >> Android SDK Platform-tools
    3. Extras >> Android Support Library
  6. You can test to see if you’ve got everything working by preforming the following:
    # Tests if the adb-server is successfully running
    adb version
    
    # NOTE:
    # If it doesn't work, don't panic (yet); try killing the server
    # (it's possible it's not even running) and restarting it:
    adb kill-server
    adb start-server
    
    
  7. Now try testing the command identified earlier again:
    adb version

    If it displays Android Debug Bridge version x.x.x, then you’ve completed the first part successfully.

Enable Development / Debugging Mode on Device

You must log into your device and access the settings to enable Development / Debugging mode:

  1. Go into Settings.
  2. Under About, you’ll be able to locate your Build Number.
  3. Tap Build Number 7 times until you are notified that you have activated Developer options.
  4. Go into Developer Options, ensure it is enabled and check the Enable OEM Unlock checkbox.
  5. While in Developer Options, ensure the USB Debugging checkbox is checked too.

Unlock the Bootloader

Once the bootloader is unlocked, your Android device will prompt you that it will erase everything.
Before proceeding with this step, make sure you’ve backed up everything important to you. Preferably you’re doing this step with a brand new device so you have nothing to lose at this time.

  1. Turn the device off (if it’s on already) and turn it back on while holding the volume down and the power button at the same time. This will start your device into the bootloader/fastboot mode.
  2. Plug the device into your PC (via a USB cable), then open a command prompt window window and type the following:
    # Create an environment variable to simplify the commands
    ASDK="$HOME/Development/Android/SDK"
    # Change to our development directory
    pushd $ASDK
    # Update our path
    export PATH="$PATH:$ASDK/tools:$ASDK/platform-tools"
    
    # list the devices detected in fastboot mode:
    fastboot devices
    

    If your device’s serial number shows up, you are good to go! If not, you’ll need to figure this part out before continuing.

  3. This next step will completely wipe EVERYTHING off of your device. Make sure to back up anything worth saving before proceeding. If you’re having second thoughts about this; now is the time to back out. You can reboot your device again and it will return how it was.

    Otherwise, for all intent and purposes, unlock the bootloader with the following command:

    fastboot oem unlock

    On the device (still attached to the computer), a screen should pop up asking whether or not you would like to unlock the bootloader. Use the volume rockers to highlight “Yes” then press power to confirm the action.
    After the above command has finished executing, run the following to restart your device:

    fastboot reboot

    The device will reboot at this time.

    Next you will be presented with a screen containing an Android logo as well as a progress bar. It can take about 8 minutes or so to finish.

    When it’s complete, it will restart and act as though it was the first time you’ve ever turned on the device. There is no sense in doing anything yet, we still have a few more steps to do. Just power off the device at this time and keep reading.

Root Your Android Device

Your bootloader must be unlocked for this step to work correctly. Otherwise, you can root your device with the following actions:

  1. Download the Chainfire‘s (CF-)Auto-Root tool to automate everything for you downloadable from here.
  2. Extract the ZIP file to your Desktop; this makes it easy to access.
  3. Turn the device off (if it’s on already) and turn it back on while holding the volume down + power button at the same time. This will start your device into the bootloader/fastboot mode.
  4. Plug the device into your PC (via a USB cable), then open a command prompt window window and type the following:
    # Create an environment variable to simplify the commands
    ASDK="$HOME/Development/Android/SDK"
    # Change to our development directory
    pushd $ASDK
    # Update our path
    export PATH="$PATH:$ASDK/tools:$ASDK/platform-tools"
    
    # Create a directory to place the Auto-Root contents in:
    mkdir -p "$ASDK/autoroot"
    
    # Uncompress contents to this directory:
    unzip CF-Auto-Root-shamu-shamu-nexus6.zip -d "$ASDK/autoroot"
    
    # Reboot your device into bootloader mode (power+volume down or this option):
    adb reboot bootloader
    
    # Now root your device with the following commands:
    IMAGE=$(find autoroot/image -type f -name '*.img')
    chmod ug+x autoroot/tools/fastboot-linux
    autoroot/tools/fastboot-linux boot "$IMAGE"
    

Upgrade Your Rooted Device

When Android v5.1 came out; the OTA failed (rebooted to an ‘error’). I had to fetch the stock version I was currently running so I could specifically just flash 2 images (system and recovery).

  1. Setup your development environment
    # Create an environment variable to simplify the commands
    ASDK="$HOME/Development/Android/SDK"
    # Change to our development directory
    pushd $ASDK
    # Update our path
    export PATH="$PATH:$ASDK/tools:$ASDK/platform-tools"
    
  2. The point of this section is you want to update your Android ‘without’ losing your data.Nexus 6 Settings Build Number

    Download the stock firmware associated with the (rooted) version currently installed on your device here. The steps below will show you how you can access what is important from what you just downloaded.

    The best way to be sure you’re downloading the correct version is to go into the About settings of your device and pay attention to Build number identified at the bottom. You just need to download and work with this version as your base.

    # 5.0.1 shamu Stock (Nexus 6); You will need to visit the following
    # website to get the right firmware for your device if it's not the
    # same version I'm using: 
    # - https://developers.google.com/android/nexus/images
    #
    wget https://dl.google.com/dl/android/aosp/shamu-lrx22c-factory-ff173fc6.tgz
    mkdir -p "$ASDK/firmware.nexus.6-shamu.5.0.1"
    tar xvfz shamu-lrx22c-factory-ff173fc6.tgz -C "$ASDK/firmware.nexus.6-shamu.5.0.1"  --strip 1
    
    # Change into our Firmware Directory
    pushd "$ASDK/firmware.nexus.6-shamu.5.0.1"
    
    ######################################
    # After previously running the update from 5.0.1 to 5.1.0
    # My Nexus was updated to LMY47D (seen from options)
    # So this can be set up as follows:
    wget https://dl.google.com/dl/android/aosp/shamu-lmy47d-factory-6c44d402.tgz
    mkdir -p "$ASDK/firmware.nexus.6-shamu.5.1.0"
    tar xvfz shamu-lmy47d-factory-6c44d402.tgz -C "$ASDK/firmware.nexus.6-shamu.5.1.0"  --strip 1
    
    # Change into our Firmware Directory
    pushd "$ASDK/firmware.nexus.6-shamu.5.1.0"
    
    ######################################
    # After the update from 5.1.0 to 5.1.1 was successful
    # I checked for the version i was running for a recovery
    # point (in the future)
    # My Nexus was updated to LMY47Z (seen from options)
    # So this can be set up as follows:
    wget https://dl.google.com/dl/android/aosp/shamu-lmy47z-factory-33951732.tgz
    mkdir -p "$ASDK/firmware.nexus.6-shamu.5.1.1"
    tar xvfz shamu-lmy47z-factory-33951732.tgz -C "$ASDK/firmware.nexus.6-shamu.5.1.1"  --strip 1
    
    # Change into our Firmware Directory
    pushd "$ASDK/firmware.nexus.6-shamu.5.1.1"
    
    ######################################
    # The below applies to any firmware previously downloaded above
    
    # Extract the system images next
    unzip *.zip -d image
    
    # Reboot your device into bootloader mode (power+volume down or this option):
    adb reboot bootloader
    
    # Flash the 2 critical images that will allow your OTA to properly
    # update itself. You will loose 'root' if you've done so.
    # Don't worry; you won't lose your data when you do this.
    fastboot flash system image/system.img
    fastboot flash recovery image/recovery.img
    
    # If you've got other boot modifications (mods) installed (such as TWRP
    # or BusyBox) running your Android device in an unencrypted mode,
    # you should additionally run the following:
    fastboot flash boot image/boot.img
    
    # If you have nothing to lose and just want to completely reset
    # your device to the version you downloaded, you can run the command:
    #    ./flash-all.sh
    # Otherwise, don't do this (to save your data)!! Just move on
    # to the next command identified below to reboot.
    
    # Your device no longer has root access at this point
    # you can reboot it now
    fastboot reboot
    
    popd
    
  3. Nexus 6 OTA UpdateAfter the reboot, you will have lost your root privileges. However, you can now upgrade using the OTA update Google provides. Once the OTA upgrade has complete, you can re-root your device using the steps already identified above.

Fantastic (Root Requiring) Apps to Install

Here are some great apps worth installing on your rooted devic:

If you’re feeling brave and want to start playing with custom firmware:

If I forgot one, or you have one to share; please feel free to let me know and I’ll add it!

TWRP Setup

TWRP allows you to backup your firmware as well as flash and install/uninstall custom firmware. It requires (Stericson) BusyBox or BusyBox Pro to work correctly. Naturally it also requires that your device is rooted already. Here are the devices TWRP support. For the Nexus 6; here is the direct link.

You can think of this application has installing 2 key components onto your device:

  • The .apk (front end application) which provides you with some rudimentary control to it’s backend. This is a simple app you just download from the Google Play store here.

    It provides you with the ability to flash the backend for you. I’ll explain how to flash it manually below; the only advantage of doing it manually is you can use some of the newer firmware that hasn’t made it back to the .apk yet. That and you know for certain you’ll flash the right ROM as using the .apk gives you the ‘chance’ to brick your device through accidental choice selections.

  • The backend itself. This is the beauty behind TWRP. It’s an image file you need to flash directly to your device (overwrite the stock version). Through this you can:
    1. Backup your entire device’s state (everything; including the firmware you’re running)
    2. Restore any previous backup you already created.
    3. Flash a new custom firmware you feel is worth trying without worry for if something goes wrong, you can just restore a backup. Note: It’s presumed that the first thing you do once you get this software installed is backup your current system so you have a good restore point.
  1. Setup your development environment
    # Create an environment variable to simplify the commands
    ASDK="$HOME/Development/Android/SDK"
    # Change to our development directory
    pushd $ASDK
    # Update our path
    export PATH="$PATH:$ASDK/tools:$ASDK/platform-tools"
    
  2. The point of this section is you want to update your Android ‘without’ losing your data.

    Download the stock firmware associated with the (rooted) version currently installed on your device here and prepare it’s content. If you have nothing to loose; the easiest way is to just flash everything using the latest stock firmware. But if you’re like me; here is the custom steps i took to upgrade from 5.0.1 to 5.1.0.

    # 2.8.6.0 shamu Stock (Nexus 6); You will need to visit the following
    # website to get the right firmware for your device if it's not the
    # same version I'm using:
    # - http://dl.twrp.me/shamu/
    
    [ ! -d "$ASDK/twrp/" ] && mkdir -p "$ASDK/twrp/"
    pushd "$ASDK/twrp/"
    # At the time; the latest image was twrp-2.8.6.0-shamu.img
    curl --referer http://dl.twrp.me/shamu/twrp-2.8.6.0-shamu.img 
         -O http://dl.twrp.me/shamu/twrp-2.8.6.0-shamu.img
    
    # Reboot your device into bootloader mode (power+volume down or this option):
    adb reboot bootloader
    
    # Flash the recovery image with TWRP's version
    fastboot flash recovery twrp-2.8.6.0-shamu.img
    
    # You now have TWRP installed
    fastboot reboot
    
    popd
    

Backup / Restore

  • TWRP allows you to preform full backups and restores of your device without the need of a PC connected to it. It doesn’t hurt to use this option. In order to do this; it needs to modify the recovery ROM of your device. But this isn’t really a big deal since you can easily flash it back to where it was using the firmware provided on Google’s website. Note: This application requires that your device is already rooted.
  • Titanimum Backup allows you to backup your applications and even clean out the ones you don’t want. This application is an absolutely MUST for all rooted devices!
  • Android SDK supports backups and restores too.Here is a great forum post explaining the whole operation in great detail; but in short the following commands will do the trick (assuming your device is powered on).
    # Create an environment variable to simplify the commands
    ASDK="$HOME/Development/Android/SDK"
    # Update our path
    export PATH="$PATH:$ASDK/tools:$ASDK/platform-tools"
    
    # Create Backup
    adb backup -f $(date +'%Y.%m.%d-nexus6.backup') -apk -shared -all
    
    # You can later restore this file with the command:
    adb restore YYYY.MM.DD-nexus6.backup
    

    The nice thing about the built in Android backup and restore commands is that they don’t require a rooted device to use. Your device has to be unlocked and connected to your PC (via USB) for this option to work though! Honestly, if your device is already rooted, then TWRP and Titanium Backup are the best solutions.

Reverting Everything Back

Sometimes you may want to revert everything back to how it was. This is especially an essential step if you have to send your device back to Google (or another carrier) to full fill it’s warranty.

  1. Setup your development environment
    # Create an environment variable to simplify the commands
    ASDK="$HOME/Development/Android/SDK"
    # Change to our development directory
    pushd $ASDK
    # Update our path
    export PATH="$PATH:$ASDK/tools:$ASDK/platform-tools"
    
  2. Download the stock firmware associated with your device here and prepare it’s content.

    # 5.0.1 shamu Stock (Nexus 6); You will need to visit the following
    # website to get the right firmware for your device if it's not the
    # same version I'm using: 
    # - https://developers.google.com/android/nexus/images
    # 2015 Jan - Updated Nexus 6 to v5.1.0; Future flashes for myself
    #            will involve treating that version as my stock instead.
    wget https://dl.google.com/dl/android/aosp/shamu-lrx22c-factory-ff173fc6.tgz
    mkdir -p "$ASDK/firmware.nexus.6-shamu.5.0.1"
    tar xvfz shamu-lrx22c-factory-ff173fc6.tgz -C "$ASDK/firmware.nexus.6-shamu.5.0.1"  --strip 1
    
    # now run the firmware restore
    pushd "$ASDK/firmware.nexus.6-shamu.5.0.1"
    # This command does it all and restarts the device when your done.
    ./flash-all.sh
    popd
    
  3. Now you need to re-lock the device. The easiest way to do this is power on the device with the power and volume down button held down.

    Note: if you are in a unique position where the volume down button doesn’t work (making it impossible to do the bootloader combination; do the following:

    • Log back into your device using any user (it really doesn’t matter); Don’t bother putting your real information in otherwise you’ll have to wait while your device downloads and re-installs all of your apps. The main thing is you need to enable the developer mode again and Debugging Mode. You will be prompted to authorize the connection within your device (make sure to do so).
    • Once Debugging Mode is enabled, you can connect your device up to your laptop and type the following:
      adb reboot bootloader
    • You can safely relock your device with the following command:
      fastboot oem lock
      

      After the above command has finished executing, run the following to restart your device:

      fastboot reboot

      The device will reboot at this time.

    Next you will be presented with a screen containing an Android logo as well as a progress bar. It can take about 8 minutes or so to finish.

    When it’s complete, it will restart and act as though it was the first time you’ve ever turned on the device. You can safely power it off now. It’s good to be shipped back to Google!

Sources

Credit

This blog took me a very long time to put together and test! If you like what you see and wish to copy and paste this HOWTO, please reference back to this blog post at the very least. It’s really all I ask.

Upgrading the MTP Support on CentOS 6

Introduction

The Media Transfer Protocol (MTP) provides us direct file access to devices such as our smart phones and other devices that choose to use the protocol. In my case, my Nexus 4 couldn’t correctly attach itself to my system. From my Google results; it seemed to be due to the version of libmtp I was running. You see, CentOS/RHEL ships with libmtp v1.0 and most of the support for cell phones that came out within the last 2 years isn’t available until v1.1. libmtp v1.1 additionally builds against most peoples FUSE implementations such as MTPfs, jmtpfs and simple-mtpfs. It’s through these FUSE/MTP implementations that we can easily mount and directly access the content on our smart phones and tablets that use the MTP protocol.

So upgrade libmtp already; why are you blogging about it?

Oh boy… well here are all the problems I faced:

  • VLC Media Player is built against this same library. Upgrading it means looking after this dependency too; or go without it (no, not going to happen).
  • Rhythmbox is also built against this same library (libmtp). Upgrading it means looking after this dependency too; or go without it (again… not going to happen).

Then the second problem… we’ve only tackled the upgrade of libmtp above if we go through with this… we still haven’t even tackled the FUSE implementation. Here are the results I had testing some of them:

  • MTPfs: At the time of this blog, the last update for this software was on February 4th, 2010. I got the software to compile by simply using the version that ships with Fedora 18 (1.1-0.3.svn20120510) but when I tried to use it, it just hung as a normal user. If I tried mounting the device as root it would fail (see below):
    $ mkdir media
    $ # As myself (non-root)
    $ mtpfs media/
    Listing raw device(s)
    Device 0 (VID=18d1 and PID=4ee1) is a Google Inc (for LG Electronics/Samsung) Nexus 4/10 (MTP).
       Found 1 device(s):
       Google Inc (for LG Electronics/Samsung): Nexus 4/10 (MTP) (18d1:4ee1) @ bus 2, dev 89
    Attempting to connect device
    libusb_open() failed!: Permission denied
    LIBMTP PANIC: Unable to initialize device
    Unable to open raw device 0
    
    $ # As root (superuser)
    $ sudo mtpfs media
    Listing raw device(s)
    Device 0 (VID=18d1 and PID=4ee2) is a Google Inc (for LG Electronics/Samsung) Nexus 4/10 (MTP+ADB).
       Found 1 device(s):
       Google Inc (for LG Electronics/Samsung): Nexus 4/10 (MTP+ADB) (18d1:4ee2) @ bus 2, dev 73
    Attempting to connect device
    Android device detected, assigning default bug flags
    Error 1: Get Storage information failed.
    Error 2: PTP Layer error 02fe: get_handles_recursively(): could not get object handles.
    Error 2: Error 02fe: PTP: Protocol error, data expected
    Listing File Information on Device with name: (NULL)
    LIBMTP_Get_Storage() failed:-1

    Now I don’t want to give MTPfs a bad name. It’s quite possible that it works really well but just not for my personal purposes. In fact it compiles perfectly in CentOS/RHEL 6 right out of the box without any modifications. Therefore just because it didn’t work for me doesn’t mean it won’t necessarily work for you. For this reason and the fact it was once maintained (up to Fedora 18) I’ll include my results with it here too.

  • jmtpfs worked the best for me. The only problems I ran into with this software was that it wasn’t already packaged for CentOS/RHEL. The only thing I had to work with for packaging it myself was a very long set of comments (see the link back to it’s official site to see what I’m talking about). That all said; the software works fantastic right out of the box. Kudos to the great work of the developer and his online support.
  • simple-mtpfs works well too but required some tweaking to make it possible. You see, simple-mtpfs relies on the new C++11 compiling features and standards (which truly are amazing BTW) but weren’t available during the release of CentOS/RHEL 6. Making these standards available by upgrading the glib core library to a newer version would be just crazy. In fact, you could seriously risk jeopardizing the stability of the OS itself since everything else would have been compiled against the old version. So, to work around this, I wrote a small patch file for portions of the simple-mtpfs code mimicking the old behavior prior to the C++11 standards.

Just hand over everything

Of course… and as always; I planned on it. Hopefully you’ll find the packages useful! Like my other blogs, the installation instructions will be near the bottom of this blog, along with the ‘do it yourself’ for those who don’t trust the sources.

First thing is first; this is what makes everything else tick:

Here are the dependencies you may or may not need to get out of the way. Note that I just went ahead and upgraded VLC to 2.0.6 (from the stock version 1.1). There may be other dependencies of libmtp you find that I didn’t simply because I didn’t use those packages. You can just assume that all of the binary packages listed below have been compiled against libmtp v1.1 (shared above).

After you’ve got libmtp correctly installed and your system appears to be right back in the state it was previously, we can now move on to adding one of the excellent FUSE/MTP packages some incredible developers have put together for us.

  • jmtpfs-0.4-1.el6.x86_64.rpm
    Author: Jason Ferrara (Website)
    Source: jmtpfs-0.4-1.el6.src.rpm
    Compilation Details: I made 1 small patch file (see here) introducing some of the nice idea’s his followers of his blog suggested for auto-mounting. I additionally had to make one small change so that his code could compile against the version of FUSE currently shipped with CentOS/RHEL 6. The only other thing I can take credit for is the rpm packaging itself; the rest of the work was that of the hard working developer who made this application possible. The spec file I wrote can be seen here.
  • simple-mtpfs-0.1-8.el6.x86_64.rpm
    Author: Peter Hatina (Website)
    Source: simple-mtpfs-0.1-8.el6.src.rpm
    Compilation Details: I created 2 separate patch files for this to properly compile in CentOS/RHEL. The first patch rolls back the C++11 coding styles to the older way of doing it (so it can compile against our existing libraries). The second patch introduces the auto-mounting for our environment (exactly how It was done in my patch for jmtpfs). To accommodate these patch files I needed to additionally update the spec file which you can view here.
  • mtpfs-1.1-0.3.svn20120510.el6.x86_64.rpm
    Author: Chris Debenham (Website)
    Source: mtpfs-1.1-0.3.svn20120510.el6.src.rpm
    Compilation Details: No magic went on here; I just grabbed the packaged code from a Fedora 18 release on pkgs.org and it compiled without any problems. Note: It appears the support for this package was dropped after Fedora 18 since it isn’t available for either Fedora 19 or 20.

Here are the source packages for those who are interested:

Show me what you did; I’m not using your stuff

In some cases you’ll need to use what I’ve done (patch wise); but to be as transparent as possible, I’ll show you how you can easily build everything and review all of what is going on before committing to using it. Now keep in mind also; there is A LOT of stuff covered here. There is libmtp itself, the dependencies issues and then finally the choice of FUSE/MTP implementation. I’ll cover the dependencies last since not everyone will have this issue.

First I set up a mock environment to work in; this allows us to do compiling outside of our native environment and means we don’t need to ever install any development libraries.

First prepare our development environment with mock if you haven’t already:

# Install 'mock' into your environment if you don't have it already
# This step will require you to be the superuser (root) in your native
# environment.
yum install -y mock

# Grant your normal every day user account access to the mock group
# This step will also require you to be the root user.
usermod -a -G mock YourNonRootUsername

At this point we can get away from the root user and build using our own user we created for our system.

Now we’ll cover libmtp v1.1 as everything revolves around this library.

# Fetch the latest copy (already packaged) of libmtp
wget http://dl.fedoraproject.org/pub/fedora/linux/development/20/source/SRPMS/l/libmtp-1.1.6-2.fc20.src.rpm
# As time goes on, this rpm may not be available, but
# you should be able to just get away with grabbing the latest
# copy of libmtp from http://pkgs.org

# Now we just rebuild it against our own environment
mock -v -r epel-6-x86_64 --resultdir=$(pwd)/results 
       --rebuild libmtp-1.1.6-2.fc20.src.rpm

# Now all our built RPMs will be in a directory
# entitled 'results' to make things easier, we'll just
# move it all into the directory we're working in now
find results -name '*.rpm' -exec mv {} . ;

# We can eliminate the results directory now
rm -rf results

Everything from this point forward assumes we have a built copy of libmtp to work with. Now we’ll focus on the FUSE/MTP options.

  • Option 1: simple-mtpfs
    # Fetch our source
    wget --output-document=simple-mtpfs-0.1-8.el6.src.rpm https://www.dropbox.com/sh/9dt7klam6ex1kpp/KEU68ZzLIv/20131015/mtp/simple-mtpfs-0.1-8.el6.src.rpm?dl=1
    
    # Initialize our Environment
    mock -v -r epel-6-x86_64 --init
    
    # Now install the nessisary dependencies for simple-mtpfs
    # which we must additionally include the libmtp package we
    # just built
    mock -v -r epel-6-x86_64 --install libmtp-1.1.6-2.el6.x86_64.rpm 
                                       libmtp-devel-1.1.6-2.el6.x86_64.rpm 
                                       fuse-devel
    
    # Now if you don't have any insecurities with source rpms you
    # can finish with the next command... or you can skip it and
    # extract all of it's content for inspection before building.
    # all of the results will appear in the 'results' directory.
    # Note: You'll want to skip this step and move to the next if
    # you have any insecurities at all.
    mock -v -r epel-6-x86_64 --no-clean 
                             --resultdir=$(pwd)/results 
                             --rebuild simple-mtpfs-0.1-8.el6.src.rpm
    
    # For those really insecure can keep reading and perform
    # the following steps instead of the single command above
    # Copy our source into the mock building environment
    mock -v -r epel-6-x86_64 --copyin simple-mtpfs-0.1-8.el6.src.rpm /builddir/build
    
    # Shell into our environment now
    mock -v -r epel-6-x86_64 --shell
    
    # Change to the build directory
    cd builddir/build
    
    # Install the source package (which will deploy within
    # the mock environment only)
    rpm -Uhi simple-mtpfs-0.1-8.el6.src.rpm
    
    # Now we can safely prepare the source for inspection.
    # - the spec file will be in the SPECS/* directory
    # - all patch files and source code will be in SOURCES/*
    #
    # Once your satisfied I'm not out to get you, you can build
    # the package:
    rpmbuild -ba SPECS/simple-mtpfs.spec
    
    # we're now done with our mock environment for now; Press Ctrl-D to
    # exit or simply type exit on the command line of our virtual
    # environment
    exit
    
    # We'll return to the directory we were previously in.  We can copy
    # out the packages we just built at this point. Ignore the warning
    # about SELinux if you get one because it doesn't impact our goals.
    mock -v -r epel-6-x86_64 --copyout /builddir/build/SRPMS/simple-mtpfs-0.1-8.el6.src.rpm .
    mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/simple-mtpfs-0.1-8.el6.x86_64.rpm .
    mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/simple-mtpfs-debuginfo-0.1-8.el6.x86_64.rpm .
    
  • Option 2: jmtpfs
    # Fetch our source
    wget --output-document=jmtpfs-0.4-1.el6.src.rpm https://www.dropbox.com/sh/9dt7klam6ex1kpp/KH6b9pmCRZ/20131015/mtp/jmtpfs-0.4-1.el6.src.rpm?dl=1
    
    # Initialize our Environment
    mock -v -r epel-6-x86_64 --init
    
    # Now install the necessary dependencies for jmtpfs
    # which we must additionally include the libmtp package we
    # just built
    mock -v -r epel-6-x86_64 --install libmtp-1.1.6-2.el6.x86_64.rpm 
                                       libmtp-devel-1.1.6-2.el6.x86_64.rpm 
                                       fuse-devel 
                                       file-devel
    
    # Now if you don't have any insecurities with source rpms you
    # can finish with the next command... or you can skip it and
    # extract all of it's content for inspection before building.
    # all of the results will appear in the 'results' directory.
    # Note: You'll want to skip this step and move to the next if
    # you have any insecurities at all.
    mock -v -r epel-6-x86_64 --no-clean 
                             --resultdir=$(pwd)/results 
                             --rebuild jmtpfs-0.4-1.el6.src.rpm
    
    # For those really insecure can keep reading and perform
    # the following steps instead of the single command above
    # Copy our source into the mock building environment
    mock -v -r epel-6-x86_64 --copyin jmtpfs-0.4-1.el6.src.rpm /builddir/build
    
    # Shell into our environment now
    mock -v -r epel-6-x86_64 --shell
    
    # Change to the build directory
    cd builddir/build
    
    # Install the source package (which will deploy within
    # the mock environment only)
    rpm -Uhi jmtpfs-0.4-1.el6.src.rpm
    
    # Now we can safely prepare the source for inspection.
    # - the spec file will be in the SPECS/* directory
    # - all patch files and source code will be in SOURCES/*
    #
    # Once your satisfied I'm not out to get you, you can build
    # the package:
    rpmbuild -ba SPECS/jmtpfs.spec
    
    # we're now done with our mock environment for now; Press Ctrl-D to
    # exit or simply type exit on the command line of our virtual
    # environment
    exit
    
    # We'll return to the directory we were previously in.  We can copy
    # out the packages we just built at this point. Ignore the warning
    # about SELinux if you get one because it doesn't impact our goals.
    mock -v -r epel-6-x86_64 --copyout /builddir/build/SRPMS/jmtpfs-0.4-1.el6.src.rpm .
    mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/jmtpfs-0.4-1.el6.x86_64.rpm .
    mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/jmtpfs-debuginfo-0.4-1.el6.x86_64.rpm .
    
  • Option 3: mtpfs
    # Fetch our source from pkgs.org
    wget http://dl.fedoraproject.org/pub/fedora/linux/releases/18/Everything/source/SRPMS/m/mtpfs-1.1-0.3.svn20120510.fc18.src.rpm
    
    # Initialize our Environment
    mock -v -r epel-6-x86_64 --init
    
    # Now install the necessary dependencies for mtpfs
    # which we must additionally include the libmtp package we
    # just built
    mock -v -r epel-6-x86_64 --install libmtp-1.1.6-2.el6.x86_64.rpm 
                                       libmtp-devel-1.1.6-2.el6.x86_64.rpm 
                                       autoconf automake libid3tag-devel 
                                       glib2-devel fuse-devel
    
    # If you have insecurities at this point, you'll need to
    # take them up with someone else since I didn't make any
    # modifications to this FUSE/MTP option at all. So we
    # just need to build from source at this point.
    mock -v -r epel-6-x86_64 --no-clean 
                             --resultdir=$(pwd)/result 
                             --rebuild mtpfs-1.1-0.3.svn20120510.fc18.src.rpm
    
    

Finally our libmtp dependency issues (if you have them).

  • Rhythmbox
    # Fetch our source from pkgs.org
    wget http://vault.centos.org/6.4/os/Source/SPackages/rhythmbox-0.12.8-1.el6.src.rpm
    
    # Initialize our Environment
    mock -v -r epel-6-x86_64 --init
    
    # Now install the necessary dependencies for Rhythmbox
    # which we must additionally include the libmtp package we
    # just built
    mock -v -r epel-6-x86_64 --install libmtp-1.1.6-2.el6.x86_64.rpm 
                                       libmtp-devel-1.1.6-2.el6.x86_64.rpm
    
    # Now we just rebuild from source using the new library
    mock -v -r epel-6-x86_64 --no-clean 
                             --resultdir=$(pwd)/results 
                             --rebuild rhythmbox-0.12.8-1.el6.src.rpm
    
    # Your rpm's will appear in the 'results' directory.
    
  • VLC
    # The catch with VLC is it's development isn't frozen with
    # the version of CentOS/RHEL like Rhythmbox does. This is because
    # if your running this, you've already chosen to link to other
    # repositories like RPMForge, ATrpms, LinuxTECH, etc.
    
    # Mock however (out of the box) does not link to these locations
    # at all. The quickest (and dirty) work around to this fix is to
    # simply install 'yum' into the mock environment which we can
    # use to fetch all of our dependencies (the best way is to actually)
    # create a new mock configuration that just includes them. But
    # everyone uses to many different alternatives; so we'll do it
    # my way :)
    
    # Fetch VLC source from the repository you use. You can do this
    # using yum if you have the --download-only rpm addon. Otherwise
    # just utilize pkgs.org and get the package:
    # http://pkgs.org/search/?keyword=vlc&search_on=name&distro=82&exact=1
    # At the time v2.0.6-1 was the version available to me.
    # You may need to adjust the below commands depending on which
    # package you get; I'll use a variable so you can set it to
    # whatever you get at the time.
    
    # If you are comfortable just using the version I have; you can
    # download it here:
    wget --output-document=vlc-2.0.6-1.el6.src.rpm https://www.dropbox.com/sh/9dt7klam6ex1kpp/pm7MCGHa9K/20131015/mtp/vlc-2.0.6-1.el6.src.rpm?dl=1
    
    # Set this variable to something else if you fetched a different
    # version
    VLCVER=2.0.6-1
    # Store our original source RPM Name; we do it this way
    # because some people might use different packages that
    # have the ending f20 (Fedora), atr (ATrpms), rf (RPMForge), etc
    # This way we're working with the same file regardless of
    # the version you picked
    VLCSRPM=$(find -name "vlc-$VLCVER.*.src.rpm" 2>/dev/null)
    
    # Make sure we found your rpm at this point
    # The following should output a file that exists
    echo $VLCSRPM
    
    # Initialize our Environment
    mock -v -r epel-6-x86_64 --init
    
    # Now install the nessisary dependencies for vlc which we must
    # additionally include the libmtp package we just built
    # including 'yum' so we'll fill all the dependencies
    mock -v -r epel-6-x86_64 --install libmtp-1.1.6-2.el6.x86_64.rpm 
                                       libmtp-devel-1.1.6-2.el6.x86_64.rpm 
                                       yum
    
    # Now this is the dirty trick I was telling you about; we'll
    # just install your current yum repositories into your mock
    # environment. This will make it really easy to fill our
    # dependency problems:
    find /etc/yum.repos.d/ -maxdepth 1 -mindepth 1 
                           -type f -name '*.repo' 
                           -exec mock -v -r epel-6-x86_64 
                                  --copyin {} /etc/yum.repos.d/ ;
    
    # Now we want to copy our VLC Source into the environment
    mock -v -r epel-6-x86_64 --copyin $VLCSRPM /builddir/build
    
    # Shell into our mock environment
    mock -v -r epel-6-x86_64 --shell
    
    # Change to our building directory
    cd /builddir/build
    
    # Install all our dependencies including our source
    yum install $(rpm -qp --requires vlc*.src.rpm | cut -d' ' -f1)
    
    # Install our source RPM
    rpm -Uhi vlc*.src.rpm
    
    # There is a chance this failed for you... if so
    # you can use the collection of rpms I built manually
    # to make it possible for me; just visit here:
    # https://www.dropbox.com/sh/9dt7klam6ex1kpp/_pczPoH-Wx/20131015/mtp/dep.vlc2.0
    # You can exit the shell (Ctrl-D) or type exit and by now
    # you should have enough info as to how you can install these
    # rpms into your mock environment using mock and --install
    
    # Now build your RPM (this can take some time):
    rpmbuild -ba SPECS/*.spec
    
    # We're now done with our mock environment for now; Press
    # Ctrl-D to exit or simply type exit on the command line
    # of our virtual environment
    exit
    
    Now just copy out our packages:
    mock -v -r epel-6-x86_64 --copyout /builddir/build/SRPMS/vlc-$VLCVER.el6.src.rpm .
    
    mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/vlc-$VLCVER.el6.x86_64.rpm .
    mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/vlc-core-$VLCVER.el6.x86_64.rpm .
    mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/vlc-extras-$VLCVER.el6.x86_64.rpm .
    mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/vlc-plugin-jack-$VLCVER.el6.x86_64.rpm
    mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/vlc-devel-$VLCVER.el6.x86_64.rpm
    mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/vlc-debuginfo-$VLCVER.el6.x86_64.rpm
    
    # You're done now! Phewf...
    

Installation

The installation will vary depending on your environment. If you are using either VLC or Rhythmbox, your life might be easier if you uninstall them now (knowing your going to re-install them again shortly).

yum remove rhythmbox vlc

Now you can install libmtp and your choice of FUSE/MTP implimentation (as root):

  • Option 1: simple-mtpfs
    yum localinstall libmtp-1.1.6-2.el6.x86_64.rpm simple-mtpfs-0.1-8.el6.x86_64.rpm
    
  • Option 2: jmtpfs
    yum localinstall libmtp-1.1.6-2.el6.x86_64.rpm jmtpfs-0.4-1.el6.x86_64.rpm
    
  • Option 3: mtpfs
    yum localinstall libmtp-1.1.6-2.el6.x86_64.rpm mtpfs-1.1-0.3.svn20120510.el6.x86_64.rpm
    

It’s important to note that you can go ahead and install all 3 options if you really wanted to (but it’s not really worth it). Pick one… if it doesn’t work well for you, try another.

Feel free to reinstall any other packaging you were using:

# VLC v2.0
yum localinstall vlc-core-2.0.6-1.el6.x86_64.rpm vlc-2.0.6-1.el6.x86_64.rpm

# Rythmbox v0.12.8
yum localinstall rhythmbox-upnp-0.12.8-1.el6.x86_64.rpm
Enable USB Debugging Mode
Enable USB Debugging Mode

It still isn’t mounting for me:

Some phones/tablets may require you to toggle the USB debugging mode of your phone and/or tablet for things to work smoothly for you. If you already have it enabled, then try disabling it. This is what I had to do with my Nexus 4 anyway; it worked beautifully for me after I toggled this option. I think this may be a bug with the current MTP v1.1 libraries that don’t seem to correctly handle the mounting of the device when being first connected. But whatever handshaking goes on, through the toggling of this option corrects the problem. I’m sure we will see this resolved in future builds.

Other MTP Alternatives

There are other alternatives; but this blog was going to be long enough just trying to share the ones I chose already.

  • FUSE Binding for Go is another alternative I didn’t test which seems to have a lot of active development on it as well. For those who aren’t familiar with The Go Programming Language, it is basically a fairly new language that is catching on with a lot of developers.
  • Gnome MTP is designed to be a simple MP3 player client for MTP based devices.

Credit

Please note that this information took me several days to put together and test thoroughly. I may not blog often; but I want to re-assure the stability and testing I put into everything I intend share.

If you like what you see and wish to copy and paste this HOWTO, please reference back to this blog post at the very least. It’s really all I ask.

Sources: