[Linuxulator] How to install Brave (Linux app) on FreeBSD 13.0+

Thanks for your efforts on this. Everything works fine, netflix etc fantastic. However I have one issue. I have a titan key setup with my google account so when I try and login to google it tries to probe udev, which causes a segfault:

Code:
ERROR:bus.cc(393)] Failed to connect to the bus: Did not receive a reply.
...
ERROR:udev_watcher.cc(51)] Failed to initialize a udev monitor.

If I chroot into /compat/ubuntu I can't start udev or dbus, should I be able to? Or am I completely misunderstanding something?

I would be interested to know if you or someone else has solved this particular issue. Brave tends to crash on my end as well any time it needs a hardware token.
 
patovm04 Regarding the Fix broken symlink step in your guide, I think it has been already solved in (at least) Ubuntu 22.10, since I used kinetic instead of focal for debootstrap to pull as the base.
 
One simple question: Why is it not possible to install a linux browser using the standard linux-emu? Why is it necessary to create that Ubuntu environment?
 
My question is why is this solution not packaged and in ports? pkg install www/brave? I mean, I don't need this solution but I would likely install it anyway.
 
I was reading the handbook Chapter 11 but still not clear how to fix ELF interpreter library issue. As brave does not launch using the https://github.com/mrclksr/linux-browser-installer script. Installation went well. But i cant launch it. I did chroot into the ubuntu system and did manually update but does not help. So what should i do? Shall i setup linux instead of ubuntu? As the app's entry is poping up on the applications ( i use KDE Plasma) but just not opens brave. ?
Also my final goal is to install brave-nightly instead of brave...
 
ELF interpreter /lib64/ld-linux-x86-64.so.2 not found, error 2
Abort trap
this is what i have got when trying to launch.

UPDATE
It is working now. brave-browser nightly. The trick is need to launch as brave-browser-nightly --no-sandbox --no-zygote --test-type --v=0
from chroot. I was using jammy as that is the latest LTS as far as i know. After updating the system just install it as you would do on a normal ubuntu regarding official brave website's instructions. At the end of the installation you might have some missing dependencies. Like:
Code:
E: Failed to fetch http://archive.ubuntu.com/ubuntu/pool/main/libx/libxcb/libxcb1_1.14-3ubuntu3_amd64.deb  400  Bad Request [IP: 185.125.190.39 80]
E: Failed to fetch http://archive.ubuntu.com/ubuntu/pool/main/w/wayland/libwayland-cursor0_1.20.0-1_amd64.deb  400  Bad Request [IP: 185.125.190.36 80]
E: Failed to fetch http://archive.ubuntu.com/ubuntu/pool/main/libt/libtheora/libtheora0_1.1.1+dfsg.1-15ubuntu4_amd64.deb  400  Bad Request [IP: 185.125.190.36 80]
E: Failed to fetch http://archive.ubuntu.com/ubuntu/pool/main/t/taglib/libtag1v5-vanilla_1.11.1+dfsg.1-3ubuntu3_amd64.deb  Error reading from server - read (104: Connection reset by peer) [IP: 185.125.190.36 80]
E: Failed to fetch http://archive.ubuntu.com/ubuntu/pool/main/libu/liburi-perl/liburi-perl_5.10-1_all.deb  400  Bad Request [IP: 185.125.190.36 80]
E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?
All you have to do is just install them manually one by one. After that run the apt install brave-browser-nightly command again. Then launch it with the flags.
Hope does help for somebody. ;)

However it is not perfect. I could launch only once. If i close the browser and want open it again i will have only the window but will be blank...Need some more investigation on it...:-/ I have to reboot the whole system (freebsd) to get work it again....I mean this is how i did but might exists some other workaround for it...
This is the terminal output when i open it and DOES WORK!!
Code:
[1444:101249:0602/224455.912611:ERROR:file_path_watcher_inotify.cc(315)] inotify_init() failed: Function not implemented (38)
[1444:101252:0602/224455.917166:ERROR:bus.cc(399)] Failed to connect to the bus: Failed to connect to socket /run/dbus/system_bus_socket: No such file or directory
[1444:101258:0602/224456.117047:ERROR:bus.cc(399)] Failed to connect to the bus: Failed to connect to socket /run/dbus/system_bus_socket: No such file or directory
[1444:101258:0602/224456.117099:ERROR:bus.cc(399)] Failed to connect to the bus: Failed to connect to socket /run/dbus/system_bus_socket: No such file or directory
[1444:1444:0602/224456.134583:ERROR:proxy_config_service_linux.cc(620)] inotify_init failed: Function not implemented (38)
[1444:101252:0602/224456.148257:ERROR:bus.cc(399)] Failed to connect to the bus: Could not parse server address: Unknown address type (examples of valid types are "tcp" and on UNIX "unix")
[1444:101252:0602/224456.148383:ERROR:bus.cc(399)] Failed to connect to the bus: Could not parse server address: Unknown address type (examples of valid types are "tcp" and on UNIX "unix")
[1444:101252:0602/224456.148415:ERROR:bus.cc(399)] Failed to connect to the bus: Could not parse server address: Unknown address type (examples of valid types are "tcp" and on UNIX "unix")
[1444:101252:0602/224456.148446:ERROR:bus.cc(399)] Failed to connect to the bus: Could not parse server address: Unknown address type (examples of valid types are "tcp" and on UNIX "unix")
[1444:101249:0602/224456.169150:ERROR:udev_watcher.cc(52)] Failed to initialize a udev monitor.
[1444:1444:0602/224456.176606:ERROR:bus.cc(399)] Failed to connect to the bus: Could not parse server address: Unknown address type (examples of valid types are "tcp" and on UNIX "unix")
[1444:1444:0602/224456.176630:ERROR:kwallet_dbus.cc(107)] Error contacting kwalletd (isEnabled)
[1444:1444:0602/224456.176697:ERROR:bus.cc(399)] Failed to connect to the bus: Could not parse server address: Unknown address type (examples of valid types are "tcp" and on UNIX "unix")
[1444:1444:0602/224456.176713:ERROR:kwallet_dbus.cc(79)] Error contacting klauncher to start kwalletd
[1444:1444:0602/224456.176831:ERROR:bus.cc(399)] Failed to connect to the bus: Could not parse server address: Unknown address type (examples of valid types are "tcp" and on UNIX "unix")
[1444:1444:0602/224456.176847:ERROR:kwallet_dbus.cc(459)] Error contacting kwalletd (close)
[1444:1444:0602/224456.179295:ERROR:chrome_browser_cloud_management_controller.cc(162)] Cloud management controller initialization aborted as CBCM is not enabled.
[1450:101271:0602/224456.208536:ERROR:file_path_watcher_inotify.cc(315)] inotify_init() failed: Function not implemented (38)
[1444:1444:0602/224456.244052:ERROR:proxy_config_service_linux.cc(620)] inotify_init failed: Function not implemented (38)
[1444:1444:0602/224456.260181:ERROR:proxy_config_service_linux.cc(620)] inotify_init failed: Function not implemented (38)
[1444:101252:0602/224456.262991:ERROR:bus.cc(399)] Failed to connect to the bus: Could not parse server address: Unknown address type (examples of valid types are "tcp" and on UNIX "unix")
[1444:101252:0602/224456.263071:ERROR:bus.cc(399)] Failed to connect to the bus: Could not parse server address: Unknown address type (examples of valid types are "tcp" and on UNIX "unix")
[1444:101252:0602/224456.453761:ERROR:bus.cc(399)] Failed to connect to the bus: Could not parse server address: Unknown address type (examples of valid types are "tcp" and on UNIX "unix")
[1444:101252:0602/224456.453807:ERROR:bus.cc(399)] Failed to connect to the bus: Could not parse server address: Unknown address type (examples of valid types are "tcp" and on UNIX "unix")
[1444:1444:0602/224456.569761:ERROR:proxy_config_service_linux.cc(620)] inotify_init failed: Function not implemented (38)
[1444:1444:0602/224456.618708:ERROR:eek:bject_proxy.cc(590)] Failed to call method: org.freedesktop.portal.Settings.Read: object_path= /org/freedesktop/portal/desktop: unknown error type:
[1444:101306:0602/224456.683446:ERROR:bus.cc(399)] Failed to connect to the bus: Failed to connect to socket /run/dbus/system_bus_socket: No such file or directory
[1444:101306:0602/224456.683706:ERROR:bus.cc(399)] Failed to connect to the bus: Failed to connect to socket /run/dbus/system_bus_socket: No such file or directory
[1444:101306:0602/224456.683838:ERROR:bus.cc(399)] Failed to connect to the bus: Failed to connect to socket /run/dbus/system_bus_socket: No such file or directory
[1444:101306:0602/224456.683963:ERROR:bus.cc(399)] Failed to connect to the bus: Failed to connect to socket /run/dbus/system_bus_socket: No such file or directory
[1444:101306:0602/224456.684016:ERROR:bus.cc(399)] Failed to connect to the bus: Failed to connect to socket /run/dbus/system_bus_socket: No such file or directory
[1449:1449:0602/224456.798331:ERROR:angle_platform_impl.cc(43)] Display.cpp:1023 (initialize): ANGLE Display::initialize error 12289: GLX is not present.
ERR: Display.cpp:1023 (initialize): ANGLE Display::initialize error 12289: GLX is not present.
[1449:1449:0602/224456.800261:ERROR:gl_display.cc(520)] EGL Driver message (Critical) eglInitialize: GLX is not present.
[1449:1449:0602/224456.800283:ERROR:gl_display.cc(790)] eglInitialize OpenGL failed with error EGL_NOT_INITIALIZED, trying next display type
[1449:1449:0602/224456.801472:ERROR:angle_platform_impl.cc(43)] Display.cpp:1023 (initialize): ANGLE Display::initialize error 12289: GLX is not present.
ERR: Display.cpp:1023 (initialize): ANGLE Display::initialize error 12289: GLX is not present.
[1449:1449:0602/224456.801505:ERROR:gl_display.cc(520)] EGL Driver message (Critical) eglInitialize: GLX is not present.
[1449:1449:0602/224456.801525:ERROR:gl_display.cc(790)] eglInitialize OpenGLES failed with error EGL_NOT_INITIALIZED
[1449:1449:0602/224456.801545:ERROR:gl_display.cc(824)] Initialization of all EGL display types failed.
[1449:1449:0602/224456.801567:ERROR:gl_ozone_egl.cc(26)] GLDisplayEGL::Initialize failed.
[1449:1449:0602/224456.835697:ERROR:angle_platform_impl.cc(43)] Display.cpp:1023 (initialize): ANGLE Display::initialize error 12289: GLX is not present.
ERR: Display.cpp:1023 (initialize): ANGLE Display::initialize error 12289: GLX is not present.
[1449:1449:0602/224456.835740:ERROR:gl_display.cc(520)] EGL Driver message (Critical) eglInitialize: GLX is not present.
[1449:1449:0602/224456.835758:ERROR:gl_display.cc(790)] eglInitialize OpenGL failed with error EGL_NOT_INITIALIZED, trying next display type
[1449:1449:0602/224456.835872:ERROR:angle_platform_impl.cc(43)] Display.cpp:1023 (initialize): ANGLE Display::initialize error 12289: GLX is not present.
ERR: Display.cpp:1023 (initialize): ANGLE Display::initialize error 12289: GLX is not present.
[1449:1449:0602/224456.835902:ERROR:gl_display.cc(520)] EGL Driver message (Critical) eglInitialize: GLX is not present.
[1449:1449:0602/224456.835919:ERROR:gl_display.cc(790)] eglInitialize OpenGLES failed with error EGL_NOT_INITIALIZED
[1449:1449:0602/224456.835936:ERROR:gl_display.cc(824)] Initialization of all EGL display types failed.
[1449:1449:0602/224456.835952:ERROR:gl_ozone_egl.cc(26)] GLDisplayEGL::Initialize failed.
[1449:1449:0602/224456.837976:ERROR:viz_main_impl.cc(186)] Exiting GPU process due to errors during initialization
[1455:1455:0602/224456.948095:ERROR:angle_platform_impl.cc(43)] Display.cpp:1023 (initialize): ANGLE Display::initialize error 12289: GLX is not present.
ERR: Display.cpp:1023 (initialize): ANGLE Display::initialize error 12289: GLX is not present.
[1455:1455:0602/224456.948157:ERROR:gl_display.cc(520)] EGL Driver message (Critical) eglInitialize: GLX is not present.
[1455:1455:0602/224456.948169:ERROR:gl_display.cc(790)] eglInitialize OpenGL failed with error EGL_NOT_INITIALIZED, trying next display type
[1455:1455:0602/224456.948273:ERROR:angle_platform_impl.cc(43)] Display.cpp:1023 (initialize): ANGLE Display::initialize error 12289: GLX is not present.
ERR: Display.cpp:1023 (initialize): ANGLE Display::initialize error 12289: GLX is not present.
[1455:1455:0602/224456.948293:ERROR:gl_display.cc(520)] EGL Driver message (Critical) eglInitialize: GLX is not present.
[1455:1455:0602/224456.948303:ERROR:gl_display.cc(790)] eglInitialize OpenGLES failed with error EGL_NOT_INITIALIZED
[1455:1455:0602/224456.948314:ERROR:gl_display.cc(824)] Initialization of all EGL display types failed.
[1455:1455:0602/224456.948324:ERROR:gl_ozone_egl.cc(26)] GLDisplayEGL::Initialize failed.
[1455:1455:0602/224456.975743:ERROR:angle_platform_impl.cc(43)] Display.cpp:1023 (initialize): ANGLE Display::initialize error 12289: GLX is not present.
ERR: Display.cpp:1023 (initialize): ANGLE Display::initialize error 12289: GLX is not present.
[1455:1455:0602/224456.975793:ERROR:gl_display.cc(520)] EGL Driver message (Critical) eglInitialize: GLX is not present.
[1455:1455:0602/224456.975812:ERROR:gl_display.cc(790)] eglInitialize OpenGL failed with error EGL_NOT_INITIALIZED, trying next display type
[1455:1455:0602/224456.975947:ERROR:angle_platform_impl.cc(43)] Display.cpp:1023 (initialize): ANGLE Display::initialize error 12289: GLX is not present.
ERR: Display.cpp:1023 (initialize): ANGLE Display::initialize error 12289: GLX is not present.
[1455:1455:0602/224456.975975:ERROR:gl_display.cc(520)] EGL Driver message (Critical) eglInitialize: GLX is not present.
[1455:1455:0602/224456.975992:ERROR:gl_display.cc(790)] eglInitialize OpenGLES failed with error EGL_NOT_INITIALIZED
[1455:1455:0602/224456.976009:ERROR:gl_display.cc(824)] Initialization of all EGL display types failed.
[1455:1455:0602/224456.976026:ERROR:gl_ozone_egl.cc(26)] GLDisplayEGL::Initialize failed.
[1455:1455:0602/224456.977922:ERROR:viz_main_impl.cc(186)] Exiting GPU process due to errors during initialization
[1456:1456:0602/224457.085794:ERROR:angle_platform_impl.cc(43)] Display.cpp:1023 (initialize): ANGLE Display::initialize error 12289: GLX is not present.
ERR: Display.cpp:1023 (initialize): ANGLE Display::initialize error 12289: GLX is not present.
[1456:1456:0602/224457.085858:ERROR:gl_display.cc(520)] EGL Driver message (Critical) eglInitialize: GLX is not present.
[1456:1456:0602/224457.085872:ERROR:gl_display.cc(790)] eglInitialize OpenGL failed with error EGL_NOT_INITIALIZED, trying next display type
[1456:1456:0602/224457.085965:ERROR:angle_platform_impl.cc(43)] Display.cpp:1023 (initialize): ANGLE Display::initialize error 12289: GLX is not present.
ERR: Display.cpp:1023 (initialize): ANGLE Display::initialize error 12289: GLX is not present.
[1456:1456:0602/224457.085983:ERROR:gl_display.cc(520)] EGL Driver message (Critical) eglInitialize: GLX is not present.
[1456:1456:0602/224457.085993:ERROR:gl_display.cc(790)] eglInitialize OpenGLES failed with error EGL_NOT_INITIALIZED
[1456:1456:0602/224457.086003:ERROR:gl_display.cc(824)] Initialization of all EGL display types failed.
[1456:1456:0602/224457.086013:ERROR:gl_ozone_egl.cc(26)] GLDisplayEGL::Initialize failed.
[1456:1456:0602/224457.111343:ERROR:angle_platform_impl.cc(43)] Display.cpp:1023 (initialize): ANGLE Display::initialize error 12289: GLX is not present.
ERR: Display.cpp:1023 (initialize): ANGLE Display::initialize error 12289: GLX is not present.
[1456:1456:0602/224457.111381:ERROR:gl_display.cc(520)] EGL Driver message (Critical) eglInitialize: GLX is not present.
[1456:1456:0602/224457.111398:ERROR:gl_display.cc(790)] eglInitialize OpenGL failed with error EGL_NOT_INITIALIZED, trying next display type
[1456:1456:0602/224457.113181:ERROR:angle_platform_impl.cc(43)] Display.cpp:1023 (initialize): ANGLE Display::initialize error 12289: GLX is not present.
ERR: Display.cpp:1023 (initialize): ANGLE Display::initialize error 12289: GLX is not present.
[1456:1456:0602/224457.113215:ERROR:gl_display.cc(520)] EGL Driver message (Critical) eglInitialize: GLX is not present.
[1456:1456:0602/224457.113230:ERROR:gl_display.cc(790)] eglInitialize OpenGLES failed with error EGL_NOT_INITIALIZED
[1456:1456:0602/224457.113249:ERROR:gl_display.cc(824)] Initialization of all EGL display types failed.
[1456:1456:0602/224457.113262:ERROR:gl_ozone_egl.cc(26)] GLDisplayEGL::Initialize failed.
[1456:1456:0602/224457.114896:ERROR:viz_main_impl.cc(186)] Exiting GPU process due to errors during initialization
[1453:101307:0602/224457.274057:ERROR:command_buffer_proxy_impl.cc(128)] ContextResult::kTransientFailure: Failed to send GpuControl.CreateCommandBuffer.
[1444:101249:0602/224459.739029:ERROR:udev_watcher.cc(52)] Failed to initialize a udev monitor.
 
This looks like the sysctl compat.linux.emul_path is not set. Have you added it in rc.conf?

Code:
No matching processes belonging to you were found
W: [(null)] caps.c: Normally all extra capabilities would be dropped now, but that's impossible because PulseAudio was built without capabilities support.
ELF interpreter /lib64/ld-linux-x86-64.so.2 not found, error 2
Abort trap

Holger tyler19820201

The issue was that I needed to change the sysctl on the HOST not on the jails of the chroot.


FINALLY
Code:
compat.linux.emul_path=/compat/ubuntu
in the sysctl.conf

Code:
pulseaudio --start --exit-idle-time=3600
in the linux-brave

13.1p2
==============================================================================================
After successful change on the host to point to /compat/ubuntu
When I launch linux-brave

Code:
No matching processes belonging to you were found
W: [(null)] caps.c: Normally all extra capabilities would be dropped now, but that's impossible because PulseAudio was built without capabilities support.
ELF interpreter /lib64/ld-linux-x86-64.so.2 not found, error 2
Abort trap
pulseaudio --start --exit-idle-time=3600
[78392:194536:0612/185649.785459:ERROR:bus.cc(399)] Failed to connect to the bus: Failed to connect to socket /var/run/dbus/system_bus_socket: No such file or directory
[78392:78392:0612/185649.857499:ERROR:ozone_platform_x11.cc(239)] Missing X server or $DISPLAY
[78392:78392:0612/185649.857514:ERROR:env.cc(255)] The platform failed to initialize.  Exiting.
 
Important notes:
1) This guide is for FreeBSD 13.0 and newer only!!
For FreeBSD 12, please see: https://forums.freebsd.org/threads/...-google-chrome-linux-binary-on-freebsd.77559/
2) This method should be valid for installing any other Chromium-based web browser (Google Chrome, Opera, Vivaldi, Edge, etc), as long as they (or their dependencies) are not Snaps/Flatpaks.
3) Most enhancements found in this tutorial were taken from/inspired by: https://github.com/mrclksr/linux-browser-installer
4) Given the many improvements made in Linuxulator and DRM drivers, we don't rely on games/linux-steam-utils workarounds anymore. Likewise, disabling DRI3 is no longer necessary.
5) Here we use an Ubuntu-based userspace, instead of default CentOS one.
6) Sound, webcam, microphone, hardware acceleration all properly work. Widevine support too (Netflix, Spotify, Amazon Prime Video, HBO Max, etc).
7) The /home and /tmp directories are shared by FreeBSD and Linux apps.
8) We now use /compat/ubuntu as Linux compat location, to avoid conflicting with CentOS-based ports. Still, be aware you can't run both Ubuntu and CentOS environments at the same time. When you want to switch back to running your CentOS-based applications, you'll need to disable Ubuntu rc.d script and enable the Linux one:
sysrc ubuntu_enable=NO && sysrc linux_enable=YES
Then reboot to make your changes take effect, or manually stop Ubuntu service and start the Linux one:
service ubuntu onestop && sysctl compat.linux.emul_path=/compat/linux && service linux start
9) I recommend (although is not a requirement as far as I know) to use tmpfs for /tmp. This is not the case when using ZFS default installation, but can be easily fixed. Assuming the ZFS pool is named "zroot":
# First reboot into single-user mode.
# Remount root filesystem as read/write:
mount -u /
# Destroy /tmp from zroot:
zfs destroy -f zroot/tmp
# Add this fstab entry:
printf "tmpfs\t/tmp\ttmpfs\trw,mode=1777\t0\t0\n" >> /etc/fstab
# Reboot back to normal multi-user mode.


Let's begin:
su
# Create Ubuntu rc.d script and make it executable:
touch /usr/local/etc/rc.d/ubuntu && chmod +x /usr/local/etc/rc.d/ubuntu

# Make it have this content:
Code:
#!/bin/sh
#
# PROVIDE: ubuntu
# REQUIRE: archdep mountlate
# KEYWORD: nojail
#
# This is a modified version of /etc/rc.d/linux
# Based on the script by mrclksr:
# https://github.com/mrclksr/linux-browser-installer/blob/main/rc.d/ubuntu.in
#
. /etc/rc.subr

name="ubuntu"
desc="Enable Ubuntu chroot, and Linux ABI"
rcvar="ubuntu_enable"
start_cmd="${name}_start"
stop_cmd=":"

unmounted()
{
    [ `stat -f "%d" "$1"` == `stat -f "%d" "$1/.."` -a \
      `stat -f "%i" "$1"` != `stat -f "%i" "$1/.."` ]
}

ubuntu_start()
{
    local _emul_path _tmpdir

    load_kld -e 'linux(aout|elf)' linux
    case `sysctl -n hw.machine_arch` in
    amd64)
        load_kld -e 'linux64elf' linux64
        ;;
    esac
    if [ -x /compat/ubuntu/sbin/ldconfigDisabled ]; then
        _tmpdir=`mktemp -d -t linux-ldconfig`
        /compat/ubuntu/sbin/ldconfig -C ${_tmpdir}/ld.so.cache
        if ! cmp -s ${_tmpdir}/ld.so.cache /compat/ubuntu/etc/ld.so.cache; then
            cat ${_tmpdir}/ld.so.cache > /compat/ubuntu/etc/ld.so.cache
        fi
        rm -rf ${_tmpdir}
    fi

    # Linux uses the pre-pts(4) tty naming scheme.
    load_kld pty

    # Handle unbranded ELF executables by defaulting to ELFOSABI_LINUX.
    if [ `sysctl -ni kern.elf64.fallback_brand` -eq "-1" ]; then
        sysctl kern.elf64.fallback_brand=3 > /dev/null
    fi

    if [ `sysctl -ni kern.elf32.fallback_brand` -eq "-1" ]; then
        sysctl kern.elf32.fallback_brand=3 > /dev/null
    fi
    sysctl compat.linux.emul_path=/compat/ubuntu

    _emul_path="/compat/ubuntu"
    unmounted "${_emul_path}/dev" && (mount -o nocover -t devfs devfs "${_emul_path}/dev" || exit 1)
    unmounted "${_emul_path}/dev/fd" && (mount -o nocover,linrdlnk -t fdescfs fdescfs "${_emul_path}/dev/fd" || exit 1)
    unmounted "${_emul_path}/dev/shm" && (mount -o nocover,mode=1777 -t tmpfs tmpfs "${_emul_path}/dev/shm" || exit 1)
    unmounted "${_emul_path}/home" && (mount -t nullfs /home "${_emul_path}/home" || exit 1)
    unmounted "${_emul_path}/proc" && (mount -o nocover -t linprocfs linprocfs "${_emul_path}/proc" || exit 1)
    unmounted "${_emul_path}/sys" && (mount -o nocover -t linsysfs linsysfs "${_emul_path}/sys" || exit 1)
    unmounted "${_emul_path}/tmp" && (mount -t nullfs /tmp "${_emul_path}/tmp" || exit 1)
    unmounted /dev/fd && (mount -o nocover -t fdescfs fdescfs /dev/fd || exit 1)
    unmounted /proc && (mount -o nocover -t procfs procfs /proc || exit 1)
    true
}

load_rc_config $name
run_rc_command "$1"

# Enable Linux compatibility layer (Ubuntu):
sysrc ubuntu_enable=YES

# Create necessary mount points for a working Linuxulator:
mkdir -p {/compat/ubuntu/dev/fd,/compat/ubuntu/dev/shm,/compat/ubuntu/home,/compat/ubuntu/tmp,/compat/ubuntu/proc,/compat/ubuntu/sys}

# Start Ubuntu service:
service ubuntu start

# Install needed packages:
pkg install debootstrap pulseaudio

# Install Ubuntu 20.04 into /compat/ubuntu:
debootstrap --arch=amd64 --no-check-gpg focal /compat/ubuntu

# Restart Ubuntu service to make sure everything is properly mounted:
service ubuntu restart

# Fix broken symlink:
cd /compat/ubuntu/lib64/ && rm ./ld-linux-x86-64.so.2 ; ln -s ../lib/x86_64-linux-gnu/ld-2.31.so ld-linux-x86-64.so.2

# Chroot into your Linux environment:
chroot /compat/ubuntu /bin/bash

# Set correct timezone inside your chroot:
printf "%b\n" "0.0 0 0.0\n0\nUTC" > /etc/adjtime
sudo dpkg-reconfigure tzdata # For some reason sudo is necessary here, otherwise it fails.

# Fix APT package manager:
printf "APT::Cache-Start 251658240;" > /etc/apt/apt.conf.d/00aptitude

# Enable more repositories:
printf "deb http://archive.ubuntu.com/ubuntu/ focal main restricted universe multiverse" > /etc/apt/sources.list

# Install required programs:
apt update ; apt install -y apt-transport-https curl fonts-symbola gnupg pulseaudio

# Add Brave signing key:
curl -s https://brave-browser-apt-release.s3.brave.com/brave-core.asc | apt-key --keyring /etc/apt/trusted.gpg.d/brave-browser-release.gpg add -

# Add Brave repository:
echo "deb [arch=amd64] https://brave-browser-apt-release.s3.brave.com/ stable main" | tee /etc/apt/sources.list.d/brave-browser-release.list

# Install Brave web browser:
apt update ; apt install -y brave-browser

# Exit chroot:
exit

# Create custom Brave wrapper script (based on the one provided by the program itself):
touch /compat/ubuntu/opt/brave.com/brave/brave-wrapper && chmod +x /compat/ubuntu/opt/brave.com/brave/brave-wrapper

# Make it contain this:
Code:
#!/compat/ubuntu/bin/bash
#
# Copyright (c) 2011 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

HERE="/opt/brave.com/brave"

# We include some xdg utilities next to the binary, and we want to prefer them
# over the system versions when we know the system versions are very old. We
# detect whether the system xdg utilities are sufficiently new to be likely to
# work for us by looking for xdg-settings. If we find it, we leave $PATH alone,
# so that the system xdg utilities (including any distro patches) will be used.
if ! which xdg-settings &> /dev/null; then
  # Old xdg utilities. Prepend $HERE to $PATH to use ours instead.
  export PATH="$HERE:$PATH"
else
  # Use system xdg utilities. But first create mimeapps.list if it doesn't
  # exist; some systems have bugs in xdg-mime that make it fail without it.
  xdg_app_dir="${XDG_DATA_HOME:-$HOME/.local/share/applications}"
  mkdir -p "$xdg_app_dir"
  [ -f "$xdg_app_dir/mimeapps.list" ] || touch "$xdg_app_dir/mimeapps.list"
fi

# Always use our versions of ffmpeg libs.
# This also makes RPMs find the compatibly-named library symlinks.
if [[ -n "$LD_LIBRARY_PATH" ]]; then
  LD_LIBRARY_PATH="$HERE:$HERE/lib:$LD_LIBRARY_PATH"
else
  LD_LIBRARY_PATH="$HERE:$HERE/lib"
fi
export LD_LIBRARY_PATH

export CHROME_VERSION_EXTRA="stable"

# We don't want bug-buddy intercepting our crashes. http://crbug.com/24120
export GNOME_DISABLE_CRASH_DIALOG=SET_BY_GOOGLE_CHROME

# Sanitize std{in,out,err} because they'll be shared with untrusted child
# processes (http://crbug.com/376567).
exec < /dev/null
exec > >(exec cat)
exec 2> >(exec cat >&2)

"$HERE/brave" --no-sandbox --test-type --v=0 "$@" || true

# Now create linux-brave launcher script and make it executable:
touch /usr/local/bin/linux-brave && chmod +x /usr/local/bin/linux-brave

# Edit it so it has this content:
Code:
#!/bin/sh

# Ensure having working sound, independently of the DE/WM in use:
get_pa_sock_path()
{
        PA_SOCK_PATH=$(sockstat | awk -v me=$(whoami) -F'[ \t]+' '
                $1 == me && $2 == "pulseaudio" && $6 ~ /native/ {
                        print $6;
                        exit 0
                }'
        )
}

get_pa_sock_path
if [ ! -S "$PA_SOCK_PATH" ]; then
        while killall pulseaudio; do
                sleep 0.5
        done
        pulseaudio --start
        get_pa_sock_path
fi
[ -S "$PA_SOCK_PATH" ] && export PULSE_SERVER=unix:$PA_SOCK_PATH

# Let the wrapped binary know that it has been run through the wrapper:
export CHROME_WRAPPER="`readlink -f "$0"`"

# Launch Brave through our custom brave-wrapper script:
/compat/ubuntu/opt/brave.com/brave/brave-wrapper "$@"

# Exit su:
exit

# Finally, make a .desktop file to launch Brave as any other app:
touch ~/.local/share/applications/brave-browser.desktop && chmod +x ~/.local/share/applications/brave-browser.desktop

# Make it look like this:
Code:
[Desktop Entry]
Type=Application
Version=1.0
Encoding=UTF-8
Name=Brave Web Browser
Comment=Access the Internet
Icon=brave-browser
Exec=/usr/local/bin/linux-brave %U
Categories=Application;Network;WebBrowser;
MimeType=text/html;text/xml;application/xhtml+xml;x-scheme-handler/http;x-scheme-handler/https;x-scheme-handler/ftp;
StartupNotify=true

*Notice: Accessing your google account won't work. It will display something like this:
"Couldn't sign you in This browser or app may not be secure. Try using a different browser. If you’re already using a supported browser, you can refresh your screen and try again to sign in."

To fix this, change your user agent to a non-chromium web browser, like Firefox for instance, and login to Gmail or any other google service (making sure to keep logged in). After this you can change your user agent back to default.
The good thing is you won't need to repeat this step later, not even when logging-in to a different account ?.
For reference, this extension worked for me: User-Agent Switcher and Manager


That's all!

Sources:
https://wiki.freebsd.org/LinuxJails
https://wiki.freebsd.org/LinuxApps
https://wiki.freebsd.org/Linuxulator
https://help.ubuntu.com/lts/installation-guide/armhf/apds04.html
https://github.com/AppImage/AppImageKit/issues/98
https://pastebin.com/1W9Fh3e9
https://github.com/mrclksr/linux-browser-installer

EDIT 1:
-Changed compat location to /compat/ubuntu and added Ubuntu rc.d script to avoid conflicts with CentOS-based ports.
-Modified Brave wrapper script to resemble better the one provided by Brave itself. Also dropped --no-zygote flag.

EDIT 2:
-Fixed sound for PWAs too.

EDIT 3:
-Added "Restart Ubuntu service" immediately after running debootstrap, to make sure everything needed is properly mounted.
Everything was OK until this step:

# Install required programs:
apt update ; apt install -y apt-transport-https curl fonts-symbola gnupg pulseaudio

The problem is like this:

Get:1 http://archive.ubuntu.com/ubuntu focal InRelease [265 kB]
Err:1 http://archive.ubuntu.com/ubuntu focal InRelease
Couldn't create temporary file /tmp/apt.conf.5MVgZR for passing config to apt-key
Reading package lists... Done
W: GPG error: http://archive.ubuntu.com/ubuntu focal InRelease: Couldn't create temporary file /tmp/apt.conf.5MVgZR for passing config to apt-key
E: The repository 'http://archive.ubuntu.com/ubuntu focal InRelease' is not signed.
N: Updating from such a repository can't be done securely, and is therefore disabled by default.
N: See apt-secure(8) manpage for repository creation and user configuration details.
Reading package lists... Done
Building dependency tree... Done
Note, selecting 'apt' instead of 'apt-transport-https'
Package gnupg is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source

E: Unable to locate package curl
E: Unable to locate package fonts-symbola
E: Package 'gnupg' has no installation candidate
E: Unable to locate package pulseaudio
root@Raul:/# curl -s https://brave-browser-apt-release.s3.brave.com/brave-core.asc | apt-key --keyring /etc/apt/trusted.gpg.d/brave-browser-release.gpg add
-
bash: curl: command not found
E: gnupg, gnupg2 and gnupg1 do not seem to be installed, but one of them is required for this operation


But things go wrong from the beginning with this command...

Writing: apt update gives...
0% {waiting for headers} , and is locked endless there.
 
Back
Top