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

Run Steam in Android phone #249

Open
FreddieOliveira opened this issue Nov 13, 2020 · 52 comments
Open

Run Steam in Android phone #249

FreddieOliveira opened this issue Nov 13, 2020 · 52 comments
Labels
Phone Issue happening on a Phone (Android / Musl / Termux...) Steam Need Steam to run

Comments

@FreddieOliveira
Copy link

FreddieOliveira commented Nov 13, 2020

I'm trying to run steam using box86 on Android using Termux. For this I managed to port docker for Android. Then, I started a 32 bit Ubuntu container with X11 forwarded, so I could run GUI programs inside it with VNC. From within this container I compiled box86 and downloaded the steam.deb for Linux from the official site. Next, I extracted the files from the .deb, patched the bin_steam.sh so I could run it as the root user and executed it. This caused the steam files to be installed in ~/.local/share/Steam. Finally I exported some variables with

export BOX86_LD_LIBRARY_PATH=~/.local/share/Steam/ubuntu12_32/steam-runtime/usr/lib/i386-linux-gnu:~/.local/share/Steam/ubuntu12_32

and ran the steam binary with box86:

cd ~/.local/share/Steam/ubuntu12_32
box86 ./steam

The first time I executed this, everything worked fine and it was able to download and install the updates.

IMG_20201112_225835

But, when I executed it again it started to fail with

Failed to load steamui.so - dlerror(): Cannot dlopen("steamui.so"/0x639b1b30, 2)

Screenshot_20201112-220015_VNC_Viewer

I googled this issue a lot but couldn't find a solution. I thought it could be related to OpenGL, but I already have libGL.so in my container from libgl-dev package. I've also already installed libappindicator1, libnm0 and libdbusmenu-gtk4 packages.

@FreddieOliveira
Copy link
Author

I've also tried using https://github.com/ptitSeb/gl4es, but the problem persisted. It was successfully able to load it

Screenshot_20201113-153941_Termux

but I still get the Failed to load steamui.so - dlerror(): Cannot dlopen("steamui.so"/0x639b1b30, 2) error

@FreddieOliveira
Copy link
Author

I gave it more testing and realized gl4es isn't working as expected. After trying to run glxgears I got the following error: undefined symbol: glXMakeCurrent

@ptitSeb
Do you know what may be causing this?
Also, does gl4es need the kernel to support framebuffer?

@ptitSeb
Copy link
Owner

ptitSeb commented Nov 15, 2020

You built gl4es for Android or for Linux? to get glXMakeCurrent, you need a Linux build, this symbol doesn't exist on Android build.

@FreddieOliveira
Copy link
Author

Despite using an Android phone, I'm trying to build gl4es for linux inside an Ubuntu container. Running uname inside the container gives me GNU/Linux. I've tried many different flags combinations for the cmake, but I can't manage to get glXMakeCurrent exported. Am I missing something?

@FreddieOliveira FreddieOliveira changed the title Run Steam in Android Run Steam in Android phone Nov 15, 2020
@ptitSeb
Copy link
Owner

ptitSeb commented Nov 15, 2020

You need to build with X11 also, and EGL.

@FreddieOliveira
Copy link
Author

FreddieOliveira commented Nov 15, 2020

Oh, cool. Now it worked! glxgears runs nicely, but unfortunately I'm still getting the Failed to load steamui.io error when running steam 😢

@ptitSeb
Copy link
Owner

ptitSeb commented Nov 15, 2020

Use BOX86_LOG=1 to see what is happening on the loading libs side of things

@FreddieOliveira
Copy link
Author

FreddieOliveira commented Nov 15, 2020

Hmm, running with BOX86_LOG=2 I got this:

Not an i386 ELF (40)
Error: reading elf header of /usr/lib/arm-linux-gnueabihf/libvdpau.so.1
Not an i386 ELF (40)
Error: reading elf header of /lib/i386-linux-gnu/libvdpau.so.1
Not an i386 ELF (40)
Error: reading elf header of /lib/i386-linux-gnu/libvdpau.so.1
Not an i386 ELF (40)
Error: reading elf header of /usr/lib/i386-linux-gnu/libvdpau.so.1
Faillure to create lib => fail
Error loading needed lib: "libvdpau.so.1"
Failure to Add dependant lib => fail
Error loading needed lib: "libavutil.so.55"
Failure to Add dependant lib => fail
Error loading needed lib: "libavcodec.so.57"
Failure to Add dependant lib => fail
Error loading needed lib: "libvideo.so"
Failure to Add dependant lib => fail
Warning: Cannot dlopen("steamui.so"/0x64103a40, 2)
 return 0x00000000

Looks like it's trying to load this libvdpau.so.1 as dependence but failing with Not an i386 ELF. I got this lib by apt install libvdpau1.

@FreddieOliveira
Copy link
Author

So, I uninstalled my libvdpau1, downloaded the i386.deb from packages.ubuntu.com and extracted the libvdpau.so.1 from this package into /usr/lib/i386-linux-gnu and now steam can correctly load this lib. Now, I'm fixing other libs dependencies.

Anyway, why was I getting Not an i386 ELF error? Wasn't box86 supposed to translate arm libs to i386?

Sorry if this may sound a stupid question, I really don't understand the inner works of box86

@ptitSeb
Copy link
Owner

ptitSeb commented Nov 16, 2020

it does, but it's not automatic. All functions ignature has to be declared first (that's what all inside src/wrapped is doing.

Also, you don't need to add dependancy yourself, you can find them in steam-runtime folder. Also, running with steam with STEAMOS=1 and STEAM_RUNTIME=1 env. var. help.

@FreddieOliveira
Copy link
Author

Indeed there are a lot of .so inside steam-runtime subfolders, but some wasn't presented and I had to download manually, like libvdpau1, libva2 and libva-x11-2.

You can simply apt install these packages, but then you'll get the Not an i386 ELF error, so I had to download the i386 deb for them.

Is there a way to make box86 use the native ARM version of these libs?

@ptitSeb
Copy link
Owner

ptitSeb commented Nov 16, 2020

Yes, there is a way; wrap them. But I'm unsure if it's interresting or easy for now. I may look at them later, to see if it can be a quick win...

@FreddieOliveira
Copy link
Author

Also, I had some progress! Now Steam doesn't fail anymore when opening, but it opens a transparent window:

Screenshot_20201116-000240331

That's the login window. I can even write my username and passwd, but I can't see anything that's going on.

The errors that box86 reports are:

Assertion Failed: Is64BitOS()
LIBGL: ERROR: EGL Error detected: EGL_BAD_ALLOC
sh: 1: /root/.local/share/Steam/ubuntu12_32/../ubuntu12_64/vulkandriverquery: Exec format error

These errors keep looping. I straced the execution, but not sure if there's anything interesting in the outputed log. Any ideas?

@ptitSeb
Copy link
Owner

ptitSeb commented Nov 16, 2020

You have an opengl issue. Steam use OpenGL to render, and that EGL error is not good! That means you don't have a correct glXContext.
(you can ignore the vulkan error, it's just steam trying to launch a 64bits program).

@FreddieOliveira
Copy link
Author

But I'm unsure if it's interresting or easy for now.

That's OK, downloading the i386 deb and extracting its files isn't a complicated process anyway.

Steam use OpenGL to render, and that EGL error is not good! That means you don't have a correct glXContext

Ooh, 😕 Do you think recompiling gl4es with some magic flag can fix this?

@ptitSeb
Copy link
Owner

ptitSeb commented Nov 16, 2020

Magic flag for build I don't think so. You can try with LIBGL_FB=3 env. var. first, to see if this (slow) method works...

@FreddieOliveira
Copy link
Author

Unfortunately, it didn't work. The behavior is still the same. But now I get the following errors instead:

LIBGL: Cannot use eglCopyBuffers, disabling it's use: LIBGL: ERROR: EGL Error detected: EGL_BAD_NATIVE_PIXMAP
LIBGL: ERROR: EGL Error detected: EGL_BAD_CONTEXT

Does this method require the kernel to support framebuffer? Because if so, I have to recompile Android kernel first. I don't even have /dev/fb0 file present.

@ptitSeb
Copy link
Owner

ptitSeb commented Nov 16, 2020

LIBGL_FB alow to switch different method to create the context. default is 0. /dev/fb0 access is 1 and 2. Method 3 is using PBuffer. If even that doesn't work; that means nothing will. There is no GLES available to gl4es I'm afraid.

@FreddieOliveira
Copy link
Author

Oh, that's sad :(

Sorry for the dumb question, but why gl4es and all this OpenGL stuff works fine in ARM running on a Raspberry, but aren't work in ARM running on a mobile phone? Does it have to do with the GPU chip used?

@ptitSeb
Copy link
Owner

ptitSeb commented Nov 16, 2020

Because the Linux that run under Android is not a full linux. Hardware drivers are missing mainly (or not accessible at least)

@FreddieOliveira
Copy link
Author

FreddieOliveira commented Nov 16, 2020

Hmm, ok, so it's a software issue, not a hardware. I realized that gl4es compiled for Raspberry and ODROID doesn't have the glXMakeCurrent symbol exported. That means somebody else creates the context. Who exactly? Can't I also use an auxiliar program in Android to create the context correctly?


EDIT: not compiled for Rasp and ODROID. Compiled for Android itself. Which enforces my question, how it is supposed to run without creating a context?

@ptitSeb
Copy link
Owner

ptitSeb commented Nov 17, 2020

You are in a Linux environement, so you need to build gl4es for linux, not android. With X11 and EGL enabled. On Android, context is already created (in the java part), that why this part (most glX function that handle Context creation) is not there.

@moocow1452
Copy link

You could try some GOG games or SteamCMD to see if the principles hold up with or without Steam.

@khanhduytran0
Copy link

khanhduytran0 commented Nov 26, 2020

I don't even have /dev/fb0 file present.

On Android, it's located on /dev/graphics/fb0. Simply do a symlink to /dev/fb0 as workaround.
(It requires root)

@Heasterian
Copy link
Contributor

@FreddieOliveira install Xephyr and use it as display with llvmpipe instead of gl4es so you have X server and more OpenGL version supported (I think that you are using software renderer anyway). I was able to run some games on Android this way with Linux Deploy. Also I recommend to use taskset -c command to target big cores.

@moocow1452
Copy link

@Heasterian Can you go into deets, as even if the Steam Client isn't cooperating, we could probably get some of those games working on phones.

@Heasterian
Copy link
Contributor

@moocow1452 Easy way for rooted phones. Install Linux Deploy > choose armhf as architecture and Debian Testing as OS in settings, also enable SSH as it's easy to set up drivers etc. form PC/SSH client on phone itself. Enable GUI and change it to X11, later you need to change Pulse Audio port to one that Xserver XSDL will give you. Now you can install os using Linux Deploy, after installation ends, install Xserver XSDL and launch system. I also recommend to use Termux as SSH or PC for rest, as you can just copy-paste commands this way.

After installation you need: sudo apt install xserver-xephyr libxcb-shm0-dev build-essential cmake wget gcc && sudo apt build-dep mesa. Now you need to compile mesa form source, same with box86, for wine, just use instruction from their sites. Keep in mind that you need i386 version of wine. I think that you will need install one package to add wine repo, but error itself will show you name of it. Before you start any app, start Xephyr with Xephyr :1 command.

As I didn't figure out how to restart systemd-binfmt in chroot, you need to run games with wull command like BOX86_NOSIGSEV=1 DISPLAY=:1 LIBGL_ALWAYS_SOFTWARE=1 GALLIUM_DRIVER=llvmpipe BOX86_LOG=1 box86 /opt/wine-devel/bin/wine wow/Wow.exe. You need to chage wine-develto wine version that you are using. export command can reset for Termux SSH client, so I'm not using it on phone.

For now, DirectX 9 games are corrupting memory when using dynarec for me. If you will have same issues, try to compile box86 without dynarec. Also, as Dynarec is using less threads on phone, you can use taskset -c 4,5,6,7 before box86 in your command to use big cores. OpenGL games are fine.

Sometimes Xephyr like to hang so you need to restart it.

Probably compiling whole https://android.googlesource.com/platform/external/virglrenderer/ repo, including vtest using bionic C library and running virgl_test_server from Android terminal could make GPU acceleration possible, but it needs 100 GB of AOSP source to compile and setting it up won't be easy anyway.

@moocow1452
Copy link

@Heasterian We could, or we can go directly to the good stuff.

https://chromium.googlesource.com/angle/angle/+/master/doc/DevSetup.md

@Heasterian
Copy link
Contributor

I'm not sure how it would work as I first see this project...
Could we use it to render image from chroot using Android app? @moocow1452

@moocow1452
Copy link

I'm not sure how it would work as I first see this project...
Could we use it to render image from chroot using Android app? @moocow1452

Android 10+ allows you to roll your own drivers in Developer Mode, and ANGLE is the Google GLES/Vulkan solution that can be built to a chip, loaded in as an APK and can be assigned apps that use those drivers to run as opposed to the system standard. If I am understanding it correctly, community drivers could be developed that focus on Games and Graphics APIs that don't have to support the rest of Android, without even having to root.

@Heasterian
Copy link
Contributor

Yes, but we need a way to get GPU acceleration inside of armhf subsystem running on Android. I'm not sure how it could help. I'm not developer. I'm just good in tweaking things and research.

@FreddieOliveira
Copy link
Author

@khanhduytran0 Oh cool, didn't know about that. Maybe now I can use some framebuffer tools, like fbi to display images inside Termux.

@moocow1452 I don't have a GOG account, only a Steam one. steamcmd works apparently fine, but I'm not sure how to download and start games using it.

@Heasterian Have you ever tried running steam instead of wine, wow.exe, etc? Would you please try that? I believe it's easier for you that already have everything set up to try than it's for me.

@Heasterian
Copy link
Contributor

@FreddieOliveira I don't know how to set up binfmt to work in chroot so I can't run Steam on my set up.

@khanhduytran0
Copy link

Yes, but we need a way to get GPU acceleration inside of armhf subsystem running on Android.

The main point is find out how to connect GLES context to glibc space (maybe use Chainfire/libcfsurface to connect to surfaceflinger then obtain GLES context there?)

@moocow1452
Copy link

Yes, but we need a way to get GPU acceleration inside of armhf subsystem running on Android.

The main point is find out how to connect GLES context to glibc space (maybe use Chainfire/libcfsurface to connect to surfaceflinger then obtain GLES context there?)

I've been talking with the ANGLE group, in theory, we could add whatever functionality we needed to into a developer driver, and run with that as an intermediary. I'm not super up on how Android does graphics, so I wouldn't know if one solution would be more effective than the other.

@FreddieOliveira
Copy link
Author

@Heasterian why is this binfmt a problem for you? I was able to run steam by simply

# export DISPLAY=:1
# export LD_LIBRARY_PATH=/root/.local/share/Steam/ubuntu12_32:/root/.local/share/Steam/ubuntu12_32/panorama
# box86 steam

The only thing that really stops steam from running, as far as I know, besides the graphics issues, is some semaphore functions it uses that's not available in standard Android kernel. To solve this you have to compile your phone's kernel with System V IPC enabled (it's located under General Setup).

What errors exactly do you get when trying to start steam?

@Heasterian
Copy link
Contributor

@FreddieOliveira Exec format error when using steam.sh to run it (It's most stable way from my experience).

@FreddieOliveira
Copy link
Author

Try running the binary directly instead of running the bash script.

export LD_LIBRARY_PATH=$HOME/.local/share/Steam/ubuntu12_32:$HOME/.local/share/Steam/ubuntu12_32/panorama
box86 ~/.local/share/Steam/ubuntu12_32/steam

Now you should probably get some missing lib or missing semaphore function error instead of format exec error.

If you don't have the ~/.local/share/Steam/ folder, that means steam isn't fully installed and you have to run the /usr/lib/steam/bin_steam.sh script first.

@alou-S
Copy link

alou-S commented May 19, 2021

@FreddieOliveira How did you even manage to start a Steam app on Android box86. I just get

/data/src/tier0/threadtools.cpp (2423) : Assertion Failed: Function not implemented
/data/src/tier0/threadtools.cpp (2020) : Assertion Failed: semaphore creation failed Success
/data/src/tier0/threadtools.cpp (1850) : Assertion Failed: Thread synchronization object is unuseable

@FreddieOliveira
Copy link
Author

I believe your kernel is missing semaphore functions. Most Android kernels ship with it disabled by default. You'll have to compile it with General Setup -> System V IPC enabled.

Here's a quick, but incomplete guide: https://gist.github.com/FreddieOliveira/efe850df7ff3951cb62d74bd770dce27#33-steam-work-in-progress

@alou-S
Copy link

alou-S commented Jul 27, 2021

@FreddieOliveira I finally got the latest kernel sources from samsung and have managed to compile it with SYSV-IPC and fixed all the issues associated with the kernel build.

But now when I run SteamCMD it runs fine the first time. But the next time when using it gives the following errors and crashes.

src/tier1/fileio.cpp (5036) : Assertion Failed: s_bExit
src/tier1/fileio.cpp (5038) : Assertion Failed: m_vecRegisteredWriters.Count() == 0
src/tier1/fileio.cpp (5098) : Assertion Failed: CFileWriterThread already exited

Sometimes it gives these errors too but in random and not together

src/tier0/threadtools.cpp (1745) : Assertion Failed: Thread synchronization object is unuseable
src/common/framefunction.cpp (149) : Assertion Failed: CFrameFunctionMgr::~CFrameFunctionMgr: non static FrameFunction[CHTTPClient::BFrameFuncHandleCompletedWorkItems] still registered

src/vstdlib/strtools.cpp (990) : Assertion Failed: pDest != NULL

All this doesn't happen when DynaRec is disabled, in which case it runs just fine but extremely slow (as expected).
Any ideas on what is wrong?

@ptitSeb
Copy link
Owner

ptitSeb commented Jul 27, 2021

That means there is a bug in the dynarec. Try to see of the main steamcmd linux load at a fixed address, and if yes, use BOX86_NODYNAREC=0xXXXXX-0xYYYYYYY to try bisect the region of the dynarec where the issue is. A region of 0x100 is good for debugging, bigger it get a bit hard. The BOX86_NODYNAREC env. var forbid the dynarec to create new block thats start between 0xXXXXXX and 0xYYYYYY (but a block that start before 0xXXXXXX can continue inside the zone, it will not be stopped)

@alou-S
Copy link

alou-S commented Jul 27, 2021

Okay I guess I should have included the entire error log,
Along with the above errors there was also the SIGSEGV all the time mostly looking like

29974|SIGSEGV @0x6287d434 (???(box86/0x6287d434)) (x86pc=0x64eb502b/???:"???", esp=0xee9299e8, stack=0xee82a000:0xee92a000 own=0xee82a000 fp=0xebec0761), for accessing 0x64eddbd0 (code=1/prot=83), db=(nil)((nil):(nil)/(nil):(nil)/???:clean, hash:0/0)

So I kept running it and logging the values for the address it had a problem in accessing.
The trend of the addresses lying between 0x63000000 and 0x65000000.
So excluding that entire range using BOX86_NODYNAREC fixed the issue. (but there was an extremely small chance still the error happened in a address outside the trend)

Anyway are there any possible downsides of excluding such a large range of addresses and also is there is more proper solution to the problem.
Also do you need any more debug info.

@ptitSeb
Copy link
Owner

ptitSeb commented Jul 27, 2021

It's not a solution, it's a trick to debug... The point would be to get a short adress range, then using a dump (I'll explain later) get the offending generated code, so I can then fix the issue.

@alou-S
Copy link

alou-S commented Jul 27, 2021

Also yeah some of the errors did mention steamclient.so

11775|SIGSEGV @0x62a17d70 (???(box86/0x62a17d70)) (x86pc=0xe3e678ca//home/alou/.local/share/Steam/steamcmd/linux32/steamclient.so:"???", esp=0xdddffa9c, stack=0xddd00000:0xdde00000 own=0xddd00000 fp=0x71), for accessing 0x1 (code=1/prot=0), db=(nil)((nil):(nil)/(nil):(nil)/???:clean, hash:0/0)

@ptitSeb
Copy link
Owner

ptitSeb commented Sep 29, 2022

I think this ticket can be closed now (steam should runs fine)?

@alou-S
Copy link

alou-S commented Sep 29, 2022

Well I have put this project on hold and since I have gotten a phone with a good enough Adreno GPU for Turnip I guess I'll try the entire thing again.

@ptitSeb ptitSeb added Steam Need Steam to run Phone Issue happening on a Phone (Android / Musl / Termux...) labels Oct 12, 2022
@AskAlice
Copy link

AskAlice commented May 3, 2023

@alou-S could try grabbing a jetson nano with LineageOS or an orange pi 5

@sassos14
Copy link

It's similar to what happened to me in void linux, i only had to download mesa-dri-32bit and started to work, in my distro it downloads some Ubuntu packages to run, and yeah it seems like an error in the 32 bit support

@youmukonpaku1337
Copy link

same issue here but can't get past steamui.so..

@youmukonpaku1337
Copy link

seems to fail because of libappindicator1 but i have it installed and it does not work...

@ptitSeb
Copy link
Owner

ptitSeb commented Aug 16, 2023

This is a super old ticket. You will need to put some log in here if you want some hint on how to fix. Also, launch steam with BOX86_LOG=1 BOX86_SHOWSEGV=1 to have all logs.
And don't forget steam needs box86+box64 to run, and libgtk2 on aarch64 to run, and a lot of dependancies (look at the install_steam.sh script for the list of armhf dependancies for debian/ubuntu/armbian).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Phone Issue happening on a Phone (Android / Musl / Termux...) Steam Need Steam to run
Projects
None yet
Development

No branches or pull requests

9 participants