How to Flash Lineage OS on an LG V20 Phone

This method will, when completed, will provide you with root and an unlocked bootloader, with fastboot available. It is a somewhat involved process, but the majority of the process has been simplified as much as possible.

WARNING!!!!This replaces your current bootloader with a debug bootloader. If you attempt to lock this bootloader you may brick your device.
Currently AT&T(H910) and Sprint(LS997) cannot return to stock because no KDZ files are available.

Once your phone is unlocked, it will no longer be covered by LG warranty @me2151.
As we cannot guarantee the proper operation of our hardware with custom software, we are not able to maintain the full scope of warranty for your device after you have unlocked the bootloader.
Because of that we have a responsibility to let you know that defects which may result from, or were caused by custom device-software may not be covered by LG warranty @me2151.

LG @me2151 can no longer guarantee the full functionality of your device after you unlock the bootloader. Unlocking your device may cause unexpected side effects that may include but are not limited to the following:
***Your device may stop working.
***Certain features and functionalities may be disabled.*
***Your device may become unsafe to the point of causing you harm.
***Your device becomes physically damaged due to overheating.
***The behavior of your device may be altered.
***Some content on your device may no longer be accessible or playable due to invalid DRM keys.*
***All your user data, settings, and accounts may disappear. (Therefore, we recommend that*you*backup all your data).
** -*Software updates delivered via LG FOTA (Firmware Over the Air) or Web Download services may not work on your device anymore.
LG @me2151 will not be responsible for the damages caused by any*custom software being flashed to your phone.

Known Issues:
AM&FM Radio no longer works
Boot time higher
No way to revert to stock(LS997/H910)
Possible overdose of root awesomeness!
Maybe more. Let us know!

Terminal Emulator
Newest SuperSU(SuperSU v2.78 SR5 or greater is needed)
Stock LS997 rom. for Sprint users only. (Fix’s numerous problems)

– ADB and fastboot setup and Installed
Terminal Emulator installed onto the phone.
– The above links downloaded and SuperSU placed on the SD Card.

Working Devices:
– Verizon (VS995)
– Sprint (LS997)
– ATT (H910)
– Korean(F800L)
Note: International Variants (E.g.H990DS) May get supported in the future, but are currently being worked on at the moment. If you attempt to use this method on Unsupported Devices(any V20 not listed in working devices) then you are in uncharted territory. It will almost definitely brick your device. YOU HAVE BEEN WARNED!!!!

This will tutorial will be broken up into 2 sections, during the second section the instructions will differ depending on the variant of the phone you are using.

Unlocking the Bootloader:

1) Copy all the files from inside the “Required Files” (Inside the unzipped “v20-root” folder) and paste it into your active ADB directory. Then copy and paste twrp-3.0.2-1-us996.img to your active ADB directory.

2) If you currently don’t have Terminal Emulator then go and download and install now.

3) Plug your device into the computer and verify ADB is working. Then;

On Windows, double-click “RUNMEFIRST.bat, DO NOT CLOSE THE LOG WINDOW THAT OPENS, then double-click “Step1.bat”

On Linux/MacOS (“#” Signifies a comment below)

# OR
bash ./

Open a Separate Terminal next to the RUNMEFIRST terminal, then type:

# OR
bash ./

When you run The sh or Bat files there will be a Permission denied error on 2 files: Flatland and Flatland64. This is normal and nothing to worry about.
3.5) Wait for a shell prompt, then type (or copy):

run-as con
chmod 0777 /storage/emulated/0/*

If you receive a permissions error when running “run-as con” then try down grading your Stock Rom to the December 2016 version and then starting over.

4) Open Up Terminal Emulator


Check if context is “Untrusted_app”

If “Untrusted_app” is displayed, Continue:
Type into Terminal Emulator:

applypatch /system/bin/atd /storage/emulated/0/dirtysanta

If it doesn’t show up as “Untrusted_app”, repeat the above steps from Number 1

5) Watch the RUNMEFIRST dialog for when it tells you to run Step2. Then;

On Windows, double-click “Step2.bat”

On Linux/MacOS, type:

# OR
Bash ./

Once step 2 is completed, you’ll be in bootloader, procced to “Flashing TWRP” section to continue.

Note/Warning: Verizon Users Vibrator will be constantly going off, until the whole process is complete (Past Android Setup Wizard).

Flashing TWRP and Fixing Varient Issues:
1) Run Step3, so TWRP can be flashed and a working boot.img flashed (Fix’s screen problem) by;

On Windows, double-click “Step3.bat”

On Linux/MacOS, type:

# OR
Bash ./

If you get message saying <waiting for device> on Step3.bat then you do not have the fastboot drivers installed(you may have the program but not the drivers).
To fix: Go to your device manager while the device is connected in fasboot and right click the item that says Android and select update drivers. Then select from internet. and let it install the drivers then try step3.bat again.
2) After you’re rebooted, pull and reinsert the battery and the hold the volume down and power button together. Select “yes” twice and the device should display a red triangle and say corrupt, then it will boot into TWRP.

3)Once in TWRP, Press Cancel on the password prompt and then swipe to allow system modifications.
Note:If you wish to make a back up now, you MUST save it to your SD card, and you cannot backup the data partition.
After the backup is complete, return to the main menu and hit wipe then select ?Format Data?, and follow the instructions there.

4) Steps below will differ, depending on what model you have, choose the correct model and follow its method.

Verizon(VS995) and ATT(H910):
4.1) Go back to Main-menu > Wipe > [Format Data] > Type ?Yes?
4.2) Go back to Main menu > Install > then Flash
4.3) Flash MK2000 kernel to fix static screen issue.
4.4) Wipe Dalvik, Data and Cache.
4.5) Go back to Main-menu > Reboot > System- Sprint(LS997):
4.1) Go back to Main-menu > Wipe > [Format Data] > Type ?Yes?
4.2) Go back to Main menu > Install > LS997 Stock Rom then Flash
4.3) Flash MK2000 kernel to fix static screen issue.
4.4) Wipe Dalvik, Data and Cache.
4.5) Go back to Main-menu > Reboot > System
4.6) Sprint users are Done at this point. You do not need anything else. Everything will work except static on boot.

Note:Any following Instructions are for all devices again.

5) During reboot you will get a Red Triangle with a “!” inside, this is normal (First boot after flashing SuperSu will show the Red triangle twice.Wait for system to boot (this will take awhile). It may appear like the system has frozen but it has not. JUST WAIT!

*****ALL USERS*****
If you encounter a “Secure Boot” Password then booting the first time you did not Format data properly.
To reiterate: To properly decrypt the device you need to boot into TWRP and go to WIPE->FORMAT DATA and you will be prompted to type “yes” to format and decrypt.

You now should have a rooted LG v20, download your favorite root checker app and verify root.
Note:For a root app to work, it will have to support Systemless root.

Now you can boot back into TWRP and flash the Lineage Recovery image to the recovery partition of your phone. This will remove TWRP from your phone but is required for installing Lineage OS. Once the recovery image is flashed, go ahead and reboot to the Lineage Recovery.

  • Now tap Factory Reset, then Format data / factory reset and continue with the formatting process. This will remove encryption and delete all files stored in the internal storage, as well as format your cache partition (if you have one).
  • Return to the main menu.
  • Sideload the LineageOS .zip package:
    • On the device, select “Apply Update”, then “Apply from ADB” to begin sideload.
  • (Optionally): If you want to install any add-ons, repeat the sideload steps above for those packages in sequence.


How can I remove the GUI from Raspbian/Debian?

$ sudo apt-get --purge remove "x11-*"

This will remove all the packages that are under x11 which is the library with all the graphical packages. the option –purge allow you to delete all the config file related.

$ sudo apt-get --purge autoremove
autoremove removes all the unused packages. There are a lot of unused packages after the first command.


How to fix raspi-config “The splash screen is not installed so cannot be activated”


You want to enable the boot splash screen on your Raspberry Pi using raspi-config, but you see this error message:

The splash screen is not installed so cannot be activated

followed by There was an error running option B3 Splash Screen


As you can find out from reading the raspi-config source code, it checks for the existence of /usr/share/plymouth/themes/pix/pix.script. In order to install this file, install the rpd-plym-splash package.


How do I enable restricted codecs to play DVD’s?

DVD support cannot be provided by default in Ubuntu due to legal and technical restrictions. Most commercial DVDs are encrypted and so require the use of decryption software in order to play them.

Use Fluendo to legally play DVDs

You can buy a commercial DVD decoder that can handle copy protection from Fluendo. It works with Linux and should be legal to use in all countries.

Use alternative decryption software

In some countries, the use of the below unlicensed decryption software is not permitted by law. Verify that you are within your rights to use it.

  1. Install libdvdnav4, libdvdread4, gstreamer1.0-plugins-bad, gstreamer1.0-plugins-ugly, and libdvd-pkg.

  2. Open a terminal window by pressing Ctrl+Alt+T.

  3. Run the command

    $ sudo dpkg-reconfigure libdvd-pkg

    and confirm in order to install libdvdcss2.


Use Instaloader to Regularly Download Photo’s from Specific Instagram Users

First, create a folder in your Pictures folder called ‘Instaloader’.

$ mkdir ~/Pictures/Instaloader

Next create a file inside that folder.

$ nano ~/Pictures/Instaloader/

Add the following to the file (replacing user’s with Instagram profile names) and save:

cd ~/Pictures/Instaloader
~/.local/bin/instaloader --fast-update user1 user2 user3

Give the file execute permissions and run it.

$ sudo chmod a+x ~/Pictures/Instaloader/

$ sudo ~/Pictures/Instaloader/

If it sucessfully executes, then add it to cron.

$ crontab -e

# DO NOT EDIT THIS FILE - edit the master and reinstall.
# (/tmp/crontab.z5YMVK/crontab installed on Fri Mar 5 07:57:15 2021)
# (Cron version -- $Id: crontab.c,v 2.13 1994/01/17 03:20:37 vixie Exp $)
# Edit this file to introduce tasks to be run by cron.
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
# For more information see the manual pages of crontab(5) and cron(8)
# m h dom mon dow command
0 0,12 * * * ~/Pictures/Instaloader/

How to get a Ledger Nano S Hardware Wallet to work with Electrum for Linux

Create a file in your home directory called and add the following:

cat < /etc/udev/rules.d/20-hw1.rules
# HW.1 / Nano
SUBSYSTEMS=="usb", ATTRS{idVendor}=="2581", ATTRS{idProduct}=="1b7c|2b7c|3b7c|4b7c", TAG+="uaccess", TAG+="udev-acl"
# Blue
SUBSYSTEMS=="usb", ATTRS{idVendor}=="2c97", ATTRS{idProduct}=="0000|0000|0001|0002|0003|0004|0005|0006|0007|0008|0009|000a|000b|000c|000d|000e|000f|0010|0011|0012|0013|0014|0015|0016|0017|0018|0019|001a|001b|001c|001d|001e|001f", TAG+="uaccess", TAG+="udev-acl"
# Nano S
SUBSYSTEMS=="usb", ATTRS{idVendor}=="2c97", ATTRS{idProduct}=="0001|1000|1001|1002|1003|1004|1005|1006|1007|1008|1009|100a|100b|100c|100d|100e|100f|1010|1011|1012|1013|1014|1015|1016|1017|1018|1019|101a|101b|101c|101d|101e|101f", TAG+="uaccess", TAG+="udev-acl"
# Aramis
SUBSYSTEMS=="usb", ATTRS{idVendor}=="2c97", ATTRS{idProduct}=="0002|2000|2001|2002|2003|2004|2005|2006|2007|2008|2009|200a|200b|200c|200d|200e|200f|2010|2011|2012|2013|2014|2015|2016|2017|2018|2019|201a|201b|201c|201d|201e|201f", TAG+="uaccess", TAG+="udev-acl"
# HW2
SUBSYSTEMS=="usb", ATTRS{idVendor}=="2c97", ATTRS{idProduct}=="0003|3000|3001|3002|3003|3004|3005|3006|3007|3008|3009|300a|300b|300c|300d|300e|300f|3010|3011|3012|3013|3014|3015|3016|3017|3018|3019|301a|301b|301c|301d|301e|301f", TAG+="uaccess", TAG+="udev-acl"
# Nano X
SUBSYSTEMS=="usb", ATTRS{idVendor}=="2c97", ATTRS{idProduct}=="0004|4000|4001|4002|4003|4004|4005|4006|4007|4008|4009|400a|400b|400c|400d|400e|400f|4010|4011|4012|4013|4014|4015|4016|4017|4018|4019|401a|401b|401c|401d|401e|401f", TAG+="uaccess", TAG+="udev-acl"

udevadm trigger
udevadm control --reload-rules

Give the file execute permissions and run it.

$ sudo chmod a+x
$ sudo ./

Install the following packages:

$ sudo apt-get install python3-dev libusb-1.0-0-dev libudev-dev python3-pip
$ python3 -m pip install btchip-python -U
$ python3 -m pip install bitbox02 -U
$ python3 -m pip install ckcc-protocol -U
$ python3 -m pip install keepkey -U
$ python3 -m pip install trezor -U

How to Setup a minimal Virtualmin LEMP Stack in CentOS 7

# yum install nano get

# nano /etc/selinux/config (and change it to disabled)

# reboot

# wget

# sh -m -b LEMP

# yum remove php* rh-php72*

# yum install rh-php73 rh-php73-php-fpm rh-php73-php-cgi rh-php73-php-mysqlnd rh-php73-php-imap rh-php73-php-curl rh-php73-php-gd rh-php73-php-xmlrpc rh-php73-php-xsl rh-php73-php-mbstring rh-php73-php-zip rh-php73-php-cli rh-php73-php-dom rh-php73-php-pdo rh-php73-php-soap rh-php73-php-json rh-php73-php-xml rh-php73-php-pear rh-php73-php-bcmath rh-php73-php-pecl-apcu rh-php73-php-pecl-apcu-devel rh-php73-php-intl -y

# nano /etc/opt/rh/rh-php73/php.ini (increase upload_max_filesize and post_max_size)

# systemctl enable rh-php73-php-fpm

# systemctl start rh-php73-php-fpm

# systemctl enable nginx

# systemctl start nginx

Now log into Virtualmin and complete the install wizard. Then setup the Fail2Ban Intrusion Detector module. Copy the following to /etc/fail2ban/jail.local if it’s empty:

enabled = true
port = ssh
enabled = true
port = ssh,sftp
filter = sshd-ddos
enabled = true
port = 10000
enabled = true
port = ftp,ftp-data,ftps,ftps-data
enabled = true
port = smtp,465,submission
enabled = true
port = pop3,pop3s,imap,imaps,submission,465,sieve
enabled = true
port = smtp,465,submission,imap3,imaps,pop3,pop3s

Also go to Webmin -> Webmin Configuration -> Authentication and tick the box to Block users with more than 4 failed logins for 1200 seconds. Then save.

Go to Webmin -> Hardware -> System Time and change the timezone to your local timezone. Then click on the ‘Time server sync’ tab and add as the timeserver hostname. Then click on the ‘Sync and Apply’ button.

Go to Virtualmin -> System Settings -> Features and Plugins and make sure all Apache plugins are unchecked (Apache website, SSL website, Protected web directories) and that the Nginx plugins are checked (Nginx website and Nginx SSL website). Go ahead and uncheck ‘BIND DNS domain’ if you are using your registrar’s nameservers or some other third party.

Go to Virtualmin -> System Settings -> Virtualmin Configuration and go to SSL settings. Make sure that ‘Request Let’s Encrypt certificate at domain creation time?’ and ‘Redirect HTTP to HTTPS by default?’ are set to ‘Yes’.

Go to Virtualmin -> System Settings -> Server Templates and click on ‘Default Settings’. Select ‘PHP Options’ from the template section dropdown and change the default PHP execution mode to FPM and save.

Getting Nextcloud to work in Virtualmin with Nginx

First, copy this file into your web root directory and access it from your browser. Then, just replace your server block with the following right before you create an admin user and set up the database (replace [X.X.X.X], [mydomain], and [port] with your own info):

    server_name nextcloud.[mydomain].com www.nextcloud.[mydomain].com;
    listen X.X.X.X;

    listen X.X.X.X:443 ssl http2;
    ssl_certificate /home/[mydomain]/domains/nextcloud.[mydomain].com/ssl.combined;
    ssl_certificate_key /home/[mydomain]/domains/nextcloud.[mydomain].com/ssl.key;
    root /home/[mydomain]/domains/nextcloud.[mydomain].com/public_html;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Robots-Tag none;
    add_header X-Download-Options noopen;
    add_header X-Permitted-Cross-Domain-Policies none;
    add_header Referrer-Policy no-referrer;
    fastcgi_hide_header X-Powered-By;
    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    location = /.well-known/carddav {
        return 301 $scheme://$host:$server_port/remote.php/dav;
    location = /.well-known/caldav {
        return 301 $scheme://$host:$server_port/remote.php/dav;
    client_max_body_size 512M;
    fastcgi_buffers 64 4K;
    gzip on;
    gzip_vary on;
    gzip_comp_level 4;
    gzip_min_length 256;
    gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
    gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/ application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
    location / {
        rewrite ^ /index.php;
    location ~ ^\/(?:build|tests|config|lib|3rdparty|templates|data)\/ {
        deny all;
    location ~ ^\/(?:\.|autotest|occ|issue|indie|db_|console) {
        deny all;
    location ~ ^\/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+)\.php(?:$|\/) {
        fastcgi_split_path_info ^(.+?\.php)(\/.*|)$;
        set $path_info $fastcgi_path_info;
        try_files $fastcgi_script_name =404;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $path_info;
        fastcgi_param HTTPS on;
        fastcgi_param modHeadersAvailable true;
        fastcgi_param front_controller_active true;
        fastcgi_pass localhost:[port];
        fastcgi_intercept_errors on;
        fastcgi_request_buffering off;
    location ~ ^\/(?:updater|oc[ms]-provider)(?:$|\/) {
        try_files $uri/ =404;
        index index.php;
    location ~ \.(?:css|js|woff2?|svg|gif|map)$ {
        try_files $uri /index.php$request_uri;
        add_header Cache-Control "public, max-age=15778463";
        add_header X-Content-Type-Options nosniff;
        add_header X-XSS-Protection "1; mode=block";
        add_header X-Robots-Tag none;
        add_header X-Download-Options noopen;
        add_header X-Permitted-Cross-Domain-Policies none;
        add_header Referrer-Policy no-referrer;
        access_log off;
    location ~ \.(?:png|html|ttf|ico|jpg|jpeg|bcmap|mp4|webm)$ {
        try_files $uri /index.php$request_uri;
        access_log off;

Improve how Nginx Handles WordPress

This is still a work in progress, but adding the following lines to your nginx.conf file should improve the way that WordPress functions on your Nginx server.

Add these lines to your http block:

client_max_body_size 512M;
fastcgi_buffers 8 16k;
fastcgi_buffer_size 32k;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains" always;

Add these lines to each server block that is running WordPress. This should give your site an A+ mark for security on Be sure to replace [X.X.X.X] and [mydomain] with your own info:

    location / {
        try_files $uri $uri/ /index.php?$args;
    listen [X.X.X.X]:443 default_server ssl http2;
    ssl_certificate /home/[mydomain]/ssl.combined;
    ssl_certificate_key /home/[mydomain]/ssl.key;
    ssl_protocols TLSv1.2;
    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout  10m;
    ssl_prefer_server_ciphers on;

I don’t think this has to do with running Nginx, but if you are getting a json parse error when you update a page and you are using the Gutenberg WordPress editor, try installing the Classic WordPress editor and see if that works better. The Gutenberg editor seems to still have some bugs.

Also, if you are getting a lot of white screens while in wp-admin, you probably need to increase your memory limit. Just add the following line to your wp-config file right above where it says ‘Thats all, stop editing!’, but make sure that the amount is not more than what is specified in your php.ini file:

define( 'WP_MEMORY_LIMIT', '128M' );


Fix: WordPress Memory Exhausted Error – Increase PHP Memory

Are you seeing an allowed memory size exhausted error in WordPress? This is one of the most common WordPress errors, and you can easily fix it by increasing the php memory limit in WordPress. In this article, we will show you how to fix WordPress memory exhausted error by increasing PHP memory.

What is WordPress Memory Exhausted Error?

WordPress is written in PHP, which is a server-side programming language. Every website needs a WordPress hosting server for it to function properly.

Web servers are just like any other computer. They need memory to efficiently run multiple applications at the same time. Server administrators allocate specific memory size to different applications including PHP.

When your WordPress code requires more memory than the default allocated memory, you get to see this error.

1Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 2348617 bytes) in /home4/xxx/public_html/wp-includes/plugin.php on line xxx
Memory exhausted error displayed on a WordPress site

By default, WordPress automatically tries to increase PHP memory limit if it is less than 64MB. However, 64MB is often not high enough.

Having said that, let’s see how to easily increase PHP memory limit in WordPress to avoid memory exhausted error.

Increase PHP Memory Limit in WordPress

First you need to edit the wp-config.php file on your WordPress site. It is located in your WordPress site’s root folder, and you will need to use an FTP client or file manager in your web hosting control panel.

Next, you need to paste this code in wp-config.php file just before the line that says ‘That’s all, stop editing! Happy blogging.’

1define( 'WP_MEMORY_LIMIT', '256M' );

This code tells WordPress to increase the PHP memory limit to 256MB.

Once you are done, you need to save your changes and upload your wp-config.php file back to your server.

You can now visit your WordPress site and memory exhausted error should disappear now.

If you are new to WordPress, then take a look at our beginners guide on how to copy and paste code from the web.

We also have a step by step guide on how to find and edit wp-config.php file.

Note: If this solution does not work for you, then this means your web hosting service provider does not allow WordPress to increase PHP memory limit. You will need to ask your web hosting provider to increase your PHP memory limit manually.

That’s all we hope this article helped you solve WordPress memory exhausted error by increasing PHP memory limit. You may also want to see our step-by-step beginner’s guide to troubleshooting WordPress errors.