Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can Proot be used to access Linux distribution from external storage such as SD card #50

Open
JanuszChmiel opened this issue Nov 6, 2018 · 24 comments

Comments

@JanuszChmiel
Copy link

I Am wondering, if is it possible to use Proot to run Linux distribution not from internal storage but rather from external SD card. I know, that it is not easy, but if is it not possible for now, which are The reasons?
My dream is to install Debian not to Android private application Area controlled by Termux, but install it to SD card. It would not require to use phones or tablets with huge internal storage.
Which issues can wait for Me if I would like to try this approach?
If this system would be usable from SD card at least till Android 6.0 not for never versions, I could be satisfied.
Thank you very much for yours advices and answer.

@ghost
Copy link

ghost commented Nov 6, 2018

Short answer: no.

File systems like FAT 12/16/32 or exFAT - only they are allowed on Android, don't have support for unix file permissions. They don't support symlinks, sockets, pipes and other special files.

That's why Termux is restricted only to internal storage. Proot, is not an exception.

Which issues can wait for Me if I would like to try this approach?

Ohh, permission denied is waiting for you there...

@JanuszChmiel
Copy link
Author

JanuszChmiel commented Nov 6, 2018 via email

@corbinlc
Copy link
Contributor

Longer answer...yes, but it is difficult. I developed a PRoot extension in the past that put everything on the sdcard (had to get around FAT naming rules) and would copy down files and their interpreter and libraries as needed. It worked for most cases, but was never stable enough. Also, I wasn't sure whether to A) push files sdcard back right away...there were some issues with this, B) push files only when the user asked to reshrink the filesystem or C) do it at every startup or D) make it a choice. I may resurrect this work since I am working on UserLAnd now and it is still a popular demand. It is a little ways down my list though as there is a lot of low hanging fruit before I get to this. So no promises, but I know that it is possible from how far I got before.

@projectextremum
Copy link

@corbinlc copying and re-copying stuff ain't best way out here. I suppose the performance will then be comparable to QEMU, so we can then use QEMU instead, at least for sake of more controls.

There existed programs like ul-exec and now there exist some rewrites of obsolete ulexec which is claimed to work. But none of them are for arm, it requires significant effort to rewrite it for arm. I think @xeffyr can provide some reasoning here.

@JanuszChmiel qemu-system-arm may fit your use case though, despite being little slower and there is a boot time unlike proot which instantly gives root shell.

And just for sake of clarity, why would someone even consider putting these rootfs into an area with write access to all apps?

michalbednarski added a commit that referenced this issue Dec 9, 2018
This is initial/PoC version, functionality is always enabled,
there's no error checking performed,
probably other things will need to be fixed

#50
@michalbednarski
Copy link
Collaborator

I've implemented something like that and just pushed to force-exec branch for experimentation. So far I've only tested with single files but appears to work. This is very alpha version of feature, no error checks are performed, parts of code outside of extension were commented out.

Modification affects execve/mmap/mmap2 syscalls. Other syscalls are not currently affected, so for full emulation of execution permissions stat and access probably should be modified as well. That is similar to what UserLAnd does so probably @corbinlc could help if we'd continue with this feature.

@projectextremum What is ul-exec? I cannot find it.

And just for sake of clarity, why would someone even consider putting these rootfs into an area with write access to all apps?

Reason is storage space, as not all devices have /sdcard emulated using same partition as /data, so this feature might be useful for some users.

@JanuszChmiel
Copy link
Author

JanuszChmiel commented Dec 9, 2018 via email

@ghost
Copy link

ghost commented Dec 9, 2018

Just tested it - works:

$ pwd
/sdcard
$ proot ./busybox
BusyBox v1.29.3 (2018-09-10 22:46:33 UTC) multi-call binary.
BusyBox is copyrighted by many authors between 1998-2015.
Licensed under GPLv2. See source distribution for detailed
copyright notices.

Usage: busybox [function [arguments]...]
   or: busybox --list[-full]
   or: busybox --install [-s] [DIR]
   or: function [arguments]...

	BusyBox is a multi-call binary that combines many common Unix
	utilities into a single executable.  Most people will create a
	link to busybox for each function they wish to use and BusyBox
	will act like whatever it was invoked as.

Currently defined functions:
	ar, arp, awk, base64, basename, bbconfig, bunzip2, bzip2, cal, cat,
	chattr, chgrp, chmod, chown, chpst, chrt, cksum, clear, cmp, comm, cp,
....

But anyway, this doesn't allow to create proot'ed environment on sdcard because FS doesn't support symlinks and other kinds of special files.

Ubuntu. Bash is not working due to missing linker symlink:

$ pwd
/sdcard/ubuntu
$ ls
bin    dev    home   media  opt    root   sbin   srv    tmp    var
boot   etc    lib    mnt    proc   run    snap   sys    usr
$ proot -R . /bin/bash
proot error: execve("/bin/bash"): No such file or directory
proot info: possible causes:
  * the program is a script but its interpreter (eg. /bin/sh) was not found;
  * the program is an ELF but its interpreter (eg. ld-linux.so) was not found;
  * the program is a foreign binary but qemu was not specified;
  * qemu does not work correctly (if specified);
  * the loader was not found or doesn't work.
fatal error: see `proot --help`.
proot error: can't chmod '/data/data/com.termux/files/usr/tmp/proot-32608-E7hccJ': No such file or directory
proot error: can't chdir to '/data/data/com.termux/files/usr/tmp': No such file or directory
$

Linker copied manually, but now bash is not working because of missing library symlink:

$ cp ./lib/aarch64-linux-gnu/ld-2.27.so ./lib/ld-linux-aarch64.so.1
$ proot -R . /bin/bash
/bin/bash: error while loading shared libraries: libtinfo.so.5: cannot open shared object file: No such file or directory

Okay, library can be renamed/copied. But it is not working anyway:

$ cp ./lib/aarch64-linux-gnu/libtinfo.so.5.9 ./lib/aarch64-linux-gnu/libtinfo.so.5
$ proot -R . /bin/bash
/bin/bash: error while loading shared libraries: libtinfo.so.5: failed to map segment from shared object

@corbinlc
Copy link
Contributor

@michalbednarski it has been a while, but this looks like a cleaner solution to part of the problem, that the sdcard is mounted noexec. There are other parts to the problem...like symlinks and a naming issues on the sdcard which is FAT, but this is much cleaner than how I was copying files to internal storage previously.

@corbinlc
Copy link
Contributor

For those issues, I had to have the rootfs actually be in internal storage, but have it consist of just symbolic links to the real files living on the sdcard. For the file names on the sdcard, I just gave them numeric values, since I couldn't use the actual names. Do you know of a more clever solution to the issues with the sdcard being FAT @michalbednarski? As you have already come up with a better solution for the noexec problem.

@ZhymabekRoman
Copy link

ZhymabekRoman commented Oct 11, 2020

Q : is it possible to install a Linux distribution on an SD card ?
Answer: Yes, you may need to have root rights on the Android system. Using the App2SD program (http://www.apps2sd.info/) you need to create a second partition on the SD card in the ext4 file system. next, you need to create a mount script and mount it to the system. It is in this program that this is done in one click. Now there are two options : you can move it completely (data, APK, and so on) Termux itself on the SD card, or just install the Linux distribution on the path : /data/sdext2.

I personally have Termux installed on the SD card using App2SD and everything is fine. By the way, do not forget that the SD card does not have very large write and read cycles, and it is possible that after an hour of use, the card will go into "read only" mode. I've already had this happen

Question : can I Move Termux to the SD card using system settings and without root rights?
Answer: probably not. System settings do not know how to move the data folder to the SD card because SD cards are formatted in FAT32 according to the standard

My original text Вопрос : Возможно ли установить Linux дистрибутив на SD карте ? Ответь: Да, возможно, для этого нужно иметь Рут права на Android системе. С помощью программы App2SD (http://www.apps2sd.info/) нужно создать второй раздел на SD карте в файловой системе ext4. Далее нужно создать скрипт монтирования и примонтировать к системе. Именно в этой программе это делается в один клик. Теперь тут два варианта : можно переместить полностью (data, APK и тому подобное) сам Termux на SD карту, или же чисто только установить Linux дистрибутив по пути : /data/sdext2.

У меня лично Termux установлен на SD карте с помощью App2SD и все отлично. Кстати, не забудьте что у SD карты циклов записи и чтения данных не совсем большие и возможно после часого использования карта уйдёт в режим "read only". У меня уже случилось такое

Вопрос : А можно ли переместить Termux в SD карту используя системные настройки и без Рут прав?
Ответ: скорее всего - нет. Системные настройки не умеют перемещать data папку в SD карту потому что SD карты по стандарту форматируются в FAT32

@ZhymabekRoman
Copy link

@xeffyr I think the question can be closed

@ghost
Copy link

ghost commented Oct 11, 2020

@ZhymabekRoman Correct, but this issue is mostly about using proot for executing programs from sdcard. That's possible, see this branch https://github.com/termux/proot/tree/force-exec, it is WIP.

@RohitVerma882
Copy link

Just tested it - works:

$ pwd
/sdcard
$ proot ./busybox
BusyBox v1.29.3 (2018-09-10 22:46:33 UTC) multi-call binary.
BusyBox is copyrighted by many authors between 1998-2015.
Licensed under GPLv2. See source distribution for detailed
copyright notices.

Usage: busybox [function [arguments]...]
   or: busybox --list[-full]
   or: busybox --install [-s] [DIR]
   or: function [arguments]...

	BusyBox is a multi-call binary that combines many common Unix
	utilities into a single executable.  Most people will create a
	link to busybox for each function they wish to use and BusyBox
	will act like whatever it was invoked as.

Currently defined functions:
	ar, arp, awk, base64, basename, bbconfig, bunzip2, bzip2, cal, cat,
	chattr, chgrp, chmod, chown, chpst, chrt, cksum, clear, cmp, comm, cp,
....

But anyway, this doesn't allow to create proot'ed environment on sdcard because FS doesn't support symlinks and other kinds of special files.

Ubuntu. Bash is not working due to missing linker symlink:

$ pwd
/sdcard/ubuntu
$ ls
bin    dev    home   media  opt    root   sbin   srv    tmp    var
boot   etc    lib    mnt    proc   run    snap   sys    usr
$ proot -R . /bin/bash
proot error: execve("/bin/bash"): No such file or directory
proot info: possible causes:
  * the program is a script but its interpreter (eg. /bin/sh) was not found;
  * the program is an ELF but its interpreter (eg. ld-linux.so) was not found;
  * the program is a foreign binary but qemu was not specified;
  * qemu does not work correctly (if specified);
  * the loader was not found or doesn't work.
fatal error: see `proot --help`.
proot error: can't chmod '/data/data/com.termux/files/usr/tmp/proot-32608-E7hccJ': No such file or directory
proot error: can't chdir to '/data/data/com.termux/files/usr/tmp': No such file or directory
$

Linker copied manually, but now bash is not working because of missing library symlink:

$ cp ./lib/aarch64-linux-gnu/ld-2.27.so ./lib/ld-linux-aarch64.so.1
$ proot -R . /bin/bash
/bin/bash: error while loading shared libraries: libtinfo.so.5: cannot open shared object file: No such file or directory

Okay, library can be renamed/copied. But it is not working anyway:

$ cp ./lib/aarch64-linux-gnu/libtinfo.so.5.9 ./lib/aarch64-linux-gnu/libtinfo.so.5
$ proot -R . /bin/bash
/bin/bash: error while loading shared libraries: libtinfo.so.5: failed to map segment from shared object

How you excuted?

@xloem
Copy link

xloem commented Jul 25, 2021

@xeffyr I think the question can be closed

Most people do not have rooted phones ...

@xloem
Copy link

xloem commented Nov 1, 2021

Bumped into this issue again. I infer the path forward is for people to contribute work so that this feature is met.

It looks like basically this means hooking system calls to provide for the needed features: making or reusing a filesystem norm to pretend the disk is fully featured. Luckily proot is already based around hooking system calls.

It might be possible to multitask here or reuse existing work by doing something like loading a loopback or other flat image or porting FUSE, or that might end up being more unnecessary work.

The branch linked above contains only one commit which adds some demonstration hooks.

There are various bounty services, as well, that could be used to pay more developers to work on this issue. We can also work on it slowly by consolidating helpful information.

EDIT: The best investment here (although not necessarily the quickest path) might be FUSE support. FUSE filesystems communicate with a pipe-like block device, "/dev/fuse" by default, that could likely be provided by something like a named pipe in a local folder. FUSE is designed to be provided by user-space kernel-emulation daemons if they are built.

The fuse protocol is simple c-struct based messaging. The kernel emulator sends calls composed of an "in" header and following data, and fuse replies with a different "out" header and following data. The headers are at https://github.com/libfuse/libfuse/blob/d709c24cbd9e1041264c551c2a4445e654eaf429/include/fuse_kernel.h#L739 and there is a struct for each message data there as well.

An implementation would hook system calls to send messages from that header to a fuse ipc channel, and in termux likely provide a fuse library that opened the ipc channel by default.

The implementations of each message handler are in https://github.com/libfuse/libfuse/blob/d709c24cbd9e1041264c551c2a4445e654eaf429/lib/fuse_lowlevel.c#L2462 but all they do are read the data, forward the call to the filesystem, and serialize and write the reply if there is one.

It would make sense to contribute work to proot or fuse upstream.

@j-romchain
Copy link

Has anyone tried mounting multiple img files to make the root filesystem? .img to allow symlinks etc, and multiple to allow > 4gb ?

@Austcool-Walker
Copy link

Austcool-Walker commented Nov 25, 2022

Just tested it - works:

$ pwd
/sdcard
$ proot ./busybox
BusyBox v1.29.3 (2018-09-10 22:46:33 UTC) multi-call binary.
BusyBox is copyrighted by many authors between 1998-2015.
Licensed under GPLv2. See source distribution for detailed
copyright notices.

Usage: busybox [function [arguments]...]
   or: busybox --list[-full]
   or: busybox --install [-s] [DIR]
   or: function [arguments]...

	BusyBox is a multi-call binary that combines many common Unix
	utilities into a single executable.  Most people will create a
	link to busybox for each function they wish to use and BusyBox
	will act like whatever it was invoked as.

Currently defined functions:
	ar, arp, awk, base64, basename, bbconfig, bunzip2, bzip2, cal, cat,
	chattr, chgrp, chmod, chown, chpst, chrt, cksum, clear, cmp, comm, cp,
....
But anyway, this doesn't allow to create proot'ed environment on sdcard because FS doesn't support symlinks and other kinds of special files.

Ubuntu. Bash is not working due to missing linker symlink:

$ pwd
/sdcard/ubuntu
$ ls
bin    dev    home   media  opt    root   sbin   srv    tmp    var
boot   etc    lib    mnt    proc   run    snap   sys    usr
$ proot -R . /bin/bash
proot error: execve("/bin/bash"): No such file or directory
proot info: possible causes:
  * the program is a script but its interpreter (eg. /bin/sh) was not found;
  * the program is an ELF but its interpreter (eg. ld-linux.so) was not found;
  * the program is a foreign binary but qemu was not specified;
  * qemu does not work correctly (if specified);
  * the loader was not found or doesn't work.
fatal error: see `proot --help`.
proot error: can't chmod '/data/data/com.termux/files/usr/tmp/proot-32608-E7hccJ': No such file or directory
proot error: can't chdir to '/data/data/com.termux/files/usr/tmp': No such file or directory
$
Linker copied manually, but now bash is not working because of missing library symlink:

$ cp ./lib/aarch64-linux-gnu/ld-2.27.so ./lib/ld-linux-aarch64.so.1
$ proot -R . /bin/bash
/bin/bash: error while loading shared libraries: libtinfo.so.5: cannot open shared object file: No such file or directory
Okay, library can be renamed/copied. But it is not working anyway:

$ cp ./lib/aarch64-linux-gnu/libtinfo.so.5.9 ./lib/aarch64-linux-gnu/libtinfo.so.5
$ proot -R . /bin/bash
/bin/bash: error while loading shared libraries: libtinfo.so.5: failed to map segment from shared object

What is the armhf equivalent of those code blocks you posted? I'm wanting to try that on my old galaxy tab a 8.0
@RohitVerma882

@ZhymabekRoman
Copy link

Has anyone tried mounting multiple img files to make the root filesystem? .img to allow symlinks etc, and multiple to allow > 4gb ?

If you have root permissions you can try it

@Austcool-Walker
Copy link

Austcool-Walker commented Nov 26, 2022

Has anyone tried mounting multiple img files to make the root filesystem? .img to allow symlinks etc, and multiple to allow > 4gb ?

If you have root permissions you can try it

How Can we create an ext4 for formatted img with a custom size with root and mount it? I want a big ext4 img because I have a 1TB sdcard so like a 100GB ext4 .img for example mounted on a path /storage/external_sd/ubuntu ?
@ZhymabekRoman Can I use fallocate -l 100G bionic.img ?

@xloem
Copy link

xloem commented Nov 26, 2022

To clarify, you presently need to perform new systems-style software development to do this without root.

The example block was made by building a proot branch from source. Are you saying the code is x86 only?

If you find other resources that help with this, such as when the user already has root, or associated with UserLAnd or with another non-Termux distribution, or can try out App2SD, posting your experience here could help visitors.

@Austcool-Walker
Copy link

To clarify, you presently need to perform new systems-style software development to do this without root.

The example block was made by building a proot branch from source. Are you saying the code is x86 only?

If you find other resources that help with this, such as when the user already has root, or associated with UserLAnd or with another non-Termux distribution, or can try out App2SD, posting your experience here could help visitors.

I have root mounting an img if it works I don't mind tbh

@Austcool-Walker
Copy link

With busybox root and truncate or in my case fallocate mkfs.ext4 /storage/external_sd/bionic.img then
tsu busybox mount -oloop /storage/external_sd/bionic /storage/external_sd/ubuntu it mounts a ext4 filesystem.
then resize2fs -d -s -p ./bionic.img 100G is attempting to resize the image to the size I need for my ubuntu install.

@Austcool-Walker
Copy link

I have no idea if I can proot or in my case busybox chroot there tho.

@Austcool-Walker
Copy link

I got the img method working with root! Proot! So yeah it can be done using a img mount all on external_sd

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants