Thursday, 29 November 2018

How to install busybox onto an Android emulator in order to access more linux commands

I have created the following script which can install busybox silently and headlessly via command line. It works on both 32-bit and 64-bit Android emulators.

Firstly, you should download busybox binary executable from https://busybox.net/downloads/binaries/ and copy it into your $HOME/bin folder.

Next, make a script called install-busybox.sh in $HOME/bin with the following content:

if [ $# == 0 ]; then
    devs="`adb devices | awk '{if(NF>0)print $0}' | sed -n '2,$p'`"
    N=`echo $devs | wc -l`
    if [ $N -gt 1 ]; then
        echo "Usage: $0 device-serial" >&2
        adb devices
        exit 1
    fi
    set -- `echo "$devs" | awk '{print $1}'`
fi

set -x

adb -s $1 root
adb -s $1 shell setenforce 0
adb -s $1 shell mount -o remount,rw /
adb -s $1 push $HOME/bin/busybox /sbin

# on 64-bit system, it fails
if [ $? != 0 ]; then
    adb -s $1 shell mount -o rw,exec,remount /mnt
    adb -s $1 shell cp -rfp '/sbin' /mnt/
    adb -s $1 shell mount /mnt/sbin /sbin
    adb -s $1 push $HOME/bin/busybox /sbin
fi

adb -s $1 shell /sbin/busybox --install -s /sbin
res=$?

set +x
if [ $res == 0 ]; then
    echo Successful
else
    echo Failed
fi


So far, I have tested it on API 26-28, but it might not work on all Android images.

Tuesday, 8 May 2018

Ubuntu HDMI extended monitor low resolution solved

It seems that recent versions of Ubuntu (16.04) has a bug in handling extended HDMI monitors. The HDMI monitor has up to 1980x1080 resolution, my laptop has up to 1366x768 resolution. Both screens have native 16:9 ratio.
However, in "mirrored display" mode, I can only select 1024x768 and 800x600 resolution as shown in the image below:


In such mode, my laptop screen has two blank strip on the left and right side. On the HDMI monitor, it shows a squashed screen (1024x768 resolution stretched to 16:9 full screen).

The solution is to use xrandr to list all display modes and add each mode into every monitor, the shell script is as follows:
displays=(`xrandr | grep '^[^ ]' | awk '{print $1}'`)

xrandr | grep "^ " | awk '{print $1}' | grep [0-9]x[0-9] | sort | uniq \
        | while read mode; do
        echo "Adding $mode ..."
        for display in ${displays[*]}; do
                xrandr --addmode $display $mode
        done
done
You just need to run this script before plugging in the HDMI cable.

Thursday, 22 February 2018

X11 tunnelling with audio

By default, X11 tunneling only support video but not audio. However, if both the server and the client is running Linux/Ubuntu, there is a way to do so. Hereby, I define 'server' as the machine running the actual program, 'client' as the machine which displays in front of the user.

The procedures are as follows:

1. Install and run paprefs, goto "Network server", check "Enable network access to local sound devices" and "Allow other machines on LAN to discover local sound devices"

2. on the client, run "start-pulseaudio-x11"

3. on the client, ssh to server with reverse SSH, "ssh -X -R 9998:localhost:4713 username@server"

4. in SSH, run the program on server, "PULSE_SERVER=localhost:9998 rhythmbox"

Monday, 5 February 2018

Installing Office2010 using PlayOnLinux on Ubuntu 16.04 with Chinese input method

  A few years ago, I posted a quite troublesome method of installing Office2010 using Wine. Some issues are neglected. Nowadays, Ubuntu has evolved to have PlayOnLinux to get you through all those troubles.

All you need to do is the following:

0. Install winbind and samba using apt-get (if not installed)

1. Install PlayOnLinux, using the following command: 

    apt install playonlinux

2. Install Office2010 using PlayOnLinux and your MS-Office install CD

3. change configuration to support Chinese (or whatever non-latin language) input by editing those .desktop files, append "env XMODIFIERS='@im=fcitx' LC_ALL=zh_CN.UTF-8" at the beginning of the Exec command:

The original command line should look like following:
Exec=/usr/share/playonlinux/playonlinux --run "Microsoft Excel 2010" %F

You need to change it into the following:
Exec=env XMODIFIERS='@im=fcitx' LC_ALL=zh_CN.UTF-8 /usr/share/playonlinux/playonlinux --run "Microsoft Excel 2010" %F

Notes:
- if you are using some other using input method system (not fcitx), change the field '@im=fcitx' accordingly
- if you are using other non-latin languages (not Chinese), change the field LC_ALL=zh_CN.UTF-8 accordingly (see language code list at https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes)
- by default, PlayOnLinux will install those .desktop files to your desktop folder (at $HOME/Desktop) and your local shared application folder (at $HOME/.local/share/applications/playonlinux*.desktop). You can drag these icons onto your Unity launcher bar for convenient launching.

4. copy the 32-bit version of t2embed.dll and fontsub.dll (in C:\windows\system32 for 32-bit Windows, in C:\windows\SysWOW64\ for 64-bit Windows) from Windows into $WINE_PREFIX/drive_c/windows/system32 so that you can save Office document into PDF with embedded fonts. Otherwise, the resultant PDF file is very big due to bitmap fonts.

5. copy all fonts files from \Windows\Fonts into $WINE_PREFIX/drive_c/windows/Fonts so that you can now use all fonts that are available in Windows.

After doing all these steps, the resulting copy of MS-Office installation should support most of the functionalities, including non-English character display and input method, all Windows and Linux fonts, space efficient save-as-PDF, and can be launched via X11 tunneling (i.e., the PlayOnLinux MS-Office is installed on the server, run on server, but the GUI is displayed at the client).

Monday, 9 October 2017

How to create a USB harddisk/flashdisk partition that can install multiple versions of Windows and Linux in both UEFI and legacy-MBR mode

  1. Download MPI_Tool_Pack_Plus_CloverLite and Easy2Boot
  2. Run "update-E2B" to create an Easy2Boot bootable partition on your USB harddisk/flashdisk. Take note that your E2B partition must be the 1st partition on the USB harddisk/flashdisk, and its size must be smaller than 137GB.
  3. Use MPI_Tool_Pack_Plus_CloverLite to convert all installation .iso to .imgPTN fat32 images (which has a sector-for-sector low-level format)
  4. Copy all .imgPTN files into respective folders in the E2B partition, Ubuntu/CentOS/Redhat images into /_ISO/LINUX folder, Windows 7/8/10 images into /_ISO/WINDOWS/WIN# folders respectively.
  5. You can also copy .iso images directly into E2B folder for Legacy(MBR)-only boot install.
  6. Run the "MAKE_THIS_DRIVE_CONTIGUOUS.cmd" in the E2B folder of the USB harddisk/flashdisk to make all files continuous.
  7. Subsequent partitions of the USB harddisk/flashdisk can still be used for storing files and data.

Friday, 15 September 2017

How to use Intel GPU for desktop display and dedicate Nvidia GPU for CUDA in Ubuntu?

[This solution has been rendered obsolete by the latest nvidia-415 driver, please see my Jan2019 post for the latest solution on this same problem]

Nowadays, most of modern desktop and laptop motherboards have a built-in Intel GPU for graphics display. In Ubuntu, if the desktop display uses Nvidia GPU (`prime-select nvidia`), then:
  1. when you are running CUDA simulations, you will often experience some lags or latency when manipulating with desktop items, e.g., switching to another desktop, maximizing/minimizing windows;
  2. you have less graphics memory for CUDA simulations since many desktop windows programs (including Windows itself) uses GPU memory for graphics acceleration.
The solution to this latency is to dedicate the Intel GPU for desktop display and dedicate the Nvidia GPU for CUDA programs. http://osdf.github.io/blog/intel-integrated-graphics-dedicated-gpu-for-cuda-and-ubuntu-1310.html has given a very sophisticated, complicated and long-winded but nonetheless working solution. We have a much simpler way of doing so.

Assuming you have correctly setup Nvidia driver and CUDA library, and you are able to run desktop and CUDA using your Nvidia GPU. Do the following two steps:
  1. prime-select intel
  2. append the following code in your .profile or .bashrc
if [ `ps aux | grep compiz | wc -l` -ge 2 ]; then
        nvpath=`echo /usr/lib/nvidia-???`
        export LD_LIBRARY_PATH=$nvpath:$LD_LIBRARY_PATH
fi
This will make all desktop 3D accelerations (desktop display programs like Xorg, compiz, and all OpenGL programs) to use Intel GPU, while all CUDA simulation programs (including nvidia-smi) will use Nvidia GPU. Of course, since the above code looks for the process named compiz to determine whether you are already inside desktop environment, thus, if you are not using Unity(3D) desktop, you need to change the process name correspondingly, otherwise, you might end up with a login loop and have to press Ctrl+Alt+F1 to switch to TTY to troubleshoot.

The principle is that in order to use GPU acceleration for CUDA programs (including nvidia-smi), your LD_LIBRARY_PATH must contain /usr/lib/nvidia-???

If later, you need to switch back to use Nvidia GPU for running desktop 3D programs like Blender, you can simply run `prime-select nvidia` and re-login.



The above solution works only on computers whose BIOS supports primary display device selection. Many CUDA-ignorant vendors such as Dell thought that whenever a dedicated GPU is plugged into PCIe, the on-board Intel GPU will never be used. Thus, their BIOS will automatically disable Intel GPU if a dedicated GPU is plugged into PCIe.

On such computers, you will see a black screen after doing the above steps. You have to forcefully set the PCI BusID of your desktop display device. To do so, first you need to obtain the PCI BusID of your Intel graphics card by running lspci:
00:02.0 Display controller: Intel Corporation Xeon E3-1200 v2/3rd Gen Core processor Graphics Controller (rev 09)
01:00.0 VGA compatible controller: NVIDIA Corporation GM206 [GeForce GTX 960] (rev a1)
Take note of the BusID of the Intel graphics card, i.e., 00:02.0. After that, you need to edit your /etc/X11/xorg.conf as below:
Section "Device"
        Identifier "intel"
        Driver "intel"
        BusID "PCI:0:2:0"
EndSection

Section "Screen"
        Identifier      "intel"
        Device          "intel"
EndSection
By doing so, you force your display device to use Intel driver on Intel GPU's PCI BusID.

Now, you can see your screen and enter desktop. But you will find out that you cannot run any CUDA program even with LD_LIBRARY_PATH=/usr/lib/nvidia-###. The reason is because Nvidia driver is loaded but never connected. You must first run the following as root once:
LD_LIBRARY_PATH=/usr/lib/nvidia-### nvidia-smi
After that, everything will work as usual. You can put the above line in your /etc/rc.local to make it auto-run every time the machine reboots.

One drawback of such a configuration is that you will not be able to see your screen before reaching the login screen unless you plug your monitor cable into Nvidia card; moreover, once you have reached the login screen, you won't be able to see TTY by pressing Ctrl+Alt+F1, regardless of whether you plug monitor into motherboard or Nvidia card.
The other drawback of this is that you cannot run from command line any GUI program that uses hardware acceleration, e.g., SDL2, OpenGL, etc. This is because your desktop is using Intel GPU, thus, any desktop GUI program that uses hardware acceleration must also use Intel GPU. So the solution is to remove /usr/lib/nvidia-### from LD_LIBRARY_PATH when running those hardware accelerated GUI programs.

Tuesday, 1 August 2017

How to port Linux executables from one system onto another?

There are many Linux distributions, e.g., Ubuntu, Redhat, CentOS, Debian, etc. Even for the same distribution, there are many versions. We often want to port a compiled executable from one system directly onto another system without re-compiling, because compilation is very tedious and time consuming.

Firstly, we need to collect all dependent dynamic libraries, use the following command:


 ldd -v <executable>

Secondly, copy your target executable (we call it <exec>) together with all dependency libraries (those *.so files after "=>") into a folder (we call it <exec-lib>), and then copy the folder onto another machine.

Lastly, you can run your target executable on the new system in the following way. Out of all your copied libraries, there is one called ld-linux*.so.* (we call it ld.so). This is the main library loader, it is used in the following way:
 ld.so --library-path <exec-lib>  <exec>

In this way, you can get rid of the notorious "GLIBC_XXX not found" error. However, if you encounter the error "FATAL: kernel too old", that means your program has used certain new features in the newer system, and then you do have to re-compile in a system with old-version kernel.