Como instalar Linux num Positivo ZX3040 ou ZX3020 (provavelmente também CCE F10-30) em dual boot (ou melhor triplo boot) com Windows e Android.

These steps explain how to install Linux and Android alongside Windows on a Positivo ZX3040 or ZX3020 in a dual boot or triple boot configuration.


product: WCBT1013 (3600937)
vendor: Positivo Informatica SA
serial: 1AG01YX6O
BIOS: UEFI 32 bit, American Megatrends Inc., version 1.7, date 06/09/2015, size: 64KiB, Specification Revision: 2.31, Revision: 5.8
Intel Bay Trail SoC
Intel(R) Atom(TM) CPU Z3735G @ 1.33GHz x86_64 model 55 stepping 8 microcode 0x829
System Memory DIMM DDR3 1GiB, width 64 bits, clock 1333MHz (0.8ns)

Intel Corporation Atom Processor Z36xxx/Z37xxx Series Graphics & Display (rev 0f)
Intel Corporation USB xHCI (rev 0f)
Encryption controller Trusted Execution Engine (rev 0f)
ISA bridge: Intel Corporation Atom Processor Z36xxx/Z37xxx Series Power Control Unit (rev 0f)
wireless RTL8723BS via sdio

Disk /dev/mmcblk0: 15.6 GB (internal flash)
Disk /dev/mmcblk2 (microSD)

Output of udevadm info --export-db.

Creating a bootable Pendrive

Pendrive Image

Download a compressed boot partition image containing Tinycore. On Windows use pkzip to unzip the file and Win32 Disk Imager to write it to a pen drive.

The pendrive capacity must be at least 4GB. Any data on the pendrive will be lost.

If You want to create the pendrive image yourself, follow the steps in the following subsections.


Using another PC, install CentOS 7 Minimal ISO on a bootable pendrive. The partition table should be GPT and the first partition on the pendrive must be VFAT. The size of the VFAT partition can be minimal (35MB). Before You can boot on the ZX3040, the following kernel must be installed.


Installing alternative kernel

Boot the pendrive on another PC. As user root do:

yum install -y ""

yum install -y kernel-ml-4.12.0-1.el7.elrepo.x86_64 Δ
e2label $(mount |grep " / " |cut -d' ' -f1) CentOS7

Boot Partition

The pendrive must contain a VFAT partition that contains the file EFI/BOOT/BOOTIA32.EFI.

This file is generated this way:
cd grub
export EFI_ARCH=i386
./configure --with-platform=efi --target=${EFI_ARCH} --program-prefix=""
cd grub-core
../grub-mkimage -d . -o bootia32.efi -O i386-efi -p /boot/grub ntfs hfs appleldr boot cat efi_gop efi_uga elf fat hfsplus iso9660 linux keylayouts memdisk minicmd part_apple ext2 extcmd xfs xnu part_bsd part_gpt search search_fs_file chain btrfs loadbios loadenv lvm minix minix2 reiserfs memrw mmap msdospart scsi loopback normal configfile gzio all_video efi_gop efi_uga gfxterm gettext echo boot chain eval

OS selection in GRUB using only volume and buttons

When in the GRUB menu, only the volume buttons are working. One can select the OS but only with the attached keyboard one can activate booting of the chosen OS.

In order to be able to boot another OS than the default one, the following patch makes the timeout continue even when a key is pressed.

--- grub-grub-2.02/grub-core/normal/menu.c      2017-04-25 11:23:16.000000000 -0300
+++ grub-grub-2.02_elmar/grub-core/normal/menu.c        2018-02-02 17:18:24.425719471 -0300
@@ -693,19 +693,21 @@ run_menu (grub_menu_t menu, int nested,
          grub_env_unset ("timeout");
           *auto_boot = 1;
          menu_fini ();
-         return default_entry;
+         return current_entry; // changed by Elmar, was: default_entry;

       c = grub_getkey_noblock ();

       if (c != GRUB_TERM_NO_KEY)
+          /* commented out by Elmar
          if (timeout >= 0)
              grub_env_unset ("timeout");
              grub_env_unset ("fallback");
              clear_timeout ();
+         */

          switch (c)
In the same partition put an appropriate /boot/grub/grub.cfg like this:
terminal_output console
set timeout_style=menu
set timeout=5
set tuned_params=""
set default=0

insmod part_gpt
insmod fat
insmod ext2

menuentry 'CentOS Linux (4.12.0) 7 (Core)' --class centos --class gnu-linux --class gnu --class os {
        set gfxpayload=1280x800
        insmod gzio
        search --no-floppy --label --set=root CentOS7
	linux /boot/vmlinuz-4.12.0-1.el7.elrepo.x86_64 root=LABEL=CentOS7 ro crashkernel=auto nomodeset LANG=en_US.UTF-8
	initrd /boot/initramfs-4.12.0-1.el7.elrepo.x86_64.img
menuentry "Microsoft Windows" {
        echo "Loading Microsoft Windows 10 ..."
        insmod chain
        chainloader /EFI/Microsoft/Boot/bootmgfw.efi

The files vmlinuz-4.12.0-1.el7.elrepo.x86_64 and initramfs-4.12.0-1.el7.elrepo.x86_64.img must be copied from the /boot directory of the linux root directory to the /boot directory of the boot partition.

In case more space is needed on the boot partition, depending on your boot language, the files cht_boot.ttf, jpn_boot.ttf, kor_boot.ttf can be removed from the directory EFI/Microsoft/Boot/Fonts.

Boot Linux on the ZX3040

UEFI Setup

After pressing the power button, when POSITIVO appears on the screen, hit F11 to Enter Setup. Disable Secure Boot in the Security Tab. Disable Quiet Boot in the Boot Tab.

Only the internal flash disk and a pendrive plugged into the detachable keyboard can be used for booting.

At power on press F11 to choose boot from pendrive.

Boot from internal flash to microSD

Afaik, there is no means to access the Windows boot partition from Windows, so Linux is needed to set up boot from internal flash, which means that booting from pendrive needs to be done first.

Copy Linux to microSD

Using another PC, copy the Linux partition from the pendrive on a microSD card. The VFAT partition is not needed on the microSD card.

"Copy the partition" means creating a partition table with a partition of appropriate size and then doing something like dd if=/dev/sda2 of=/dev/sdb1

Depending on the capacity of the microSD, one can increase the partition size using a tool like gparted and/or create additional partitions on the microSD.

Set up dual boot

On the ZX3040, boot from pendrive and log in as root to be able to set up boot from microSD.

Mount USB pendrive boot partition and Windows boot partition:
cd /mnt
mkdir pd
mount /dev/sda1 pd
mkdir wb
mount /dev/mmcblk0p2 wb 

The newest version of Windows 10 uses /dev/mmcblk0p2 as boot partition, an older version that came preinstalled used /dev/mmcblk0p1

Move away Windows files and copy files from pendrive to Windows boot partition:
mv wb/EFI/BOOT/Microsoft wb/EFI/BOOT/Microsaft
mv wb/EFI/BOOT/bootia32.efi wb/EFI/BOOT/bootia32_win.efi
cp pd/EFI/BOOT/bootia32.efi wb/EFI/BOOT/
cp -r pd/boot wb/
cp /boot/vmlinuz-4.12.0-1.el7.elrepo.x86_64 wb/boot
cp /boot/initramfs-4.12.0-1.el7.elrepo.x86_64.img wb/boot

If the Windows boot partition is at /dev/mmcblk0p1, You need to edit the file grub.cfg accordingly (set root='hd0,gpt1').

Shut down:
systemctl poweroff

Remove the pendrive and insert the microSD card into its slot in the ZX3040. Power on and when the word "POSITIVO" appears hit F11 and option "UEFI OS" will appear on the menu. This option leads to grub. The option "UEFI OS" will not appear if You omitted the mv .../Microsoft .../Microsaft.

In BIOS setup one can set UEFI OS as the default.

After the first successful boot, you should do
mv wb/EFI/BOOT/Microsaft wb/EFI/BOOT/Microsoft 

for Windows updates to work correctly.


Kernel .config

5.17: CONFIG_RTL8723BS=m

5.15: Works out of the box.

To connect to an access point named LAD use the command:
nmcli dev wifi connect LAD password ....
and replace .... by the password.


In kernel 4.19, no patch is needed.

Kernel .config


Command to compile kernel: make -j3 INSTALL_MOD_STRIP=1 binrpm-pkg


copy rtlbt_fw to /usr/lib/firmware/rtl_bt/rtl8723bs_fw.bin
copy rtlbt_config to /usr/lib/firmware/rtl_bt/rtl8723bs_config-OBDA8723.bin


Start the Bluez command line client:
keep looking for devices nearby:
power on
agent on
pairable on
discoverable on
scan on
Note the MAC address of the devices that you wish to pair. E.g.:
Pair with the device:
pair FC:58:FA:B0:F4:5C
Connect with the device:
connect FC:58:FA:B0:F4:5C
Trust the device (no need to answer yes to accept services):
trust FC:58:FA:B0:F4:5C
Send a file as user:
bluetooth-sendto <filename>

for headset:

cat -> /etc/bluetooth/audio.conf 

In case of problems clean up diretory /var/lib/bluetooth.

3G Modem

ZTE K3565-Z, Vendor 19d2, Product 0063


yum install usb_modeswitch ModemManager libqmi-utils
cat ->/etc/qmi-network.conf for Brazil for Europe


add at /usr/bin/qmi-network line 338:
    if [ -n "$IP_TYPE" ]; then


Needs to be done every time after the USB dongle is inserted:

qmicli -d /dev/cdc-wdm0 --dms-uim-verify-pin=PIN,XXXX only for Europe
qmi-network /dev/cdc-wdm0 start && dhclient wwp0s20u2u2i4


should be done before disconnecting USB dongle or to restart dongle without disconnecting it:
qmi-network /dev/cdc-wdm0 stop && killall dhclient


Kernel .config

From 5.3 on not needed.


Copy firmware from to /usr/lib/firmware/intel.

Follow instructions in

blacklist hdmi_lpe_audio

Backup here.

Kernel 4.19 working mic.


The Linux system partition should be at least 10 GB to use X.

yum groupinstall "X Window System"
yum install gnome-classic-session

Use lightweight:

FLWM Window Manager - copy it to /usr/local/bin and chmod +x
copy flwm.desktop to /usr/share/xsessions/ and link user's .xinitrc to it

Touch Screen

Works out of the box for kernel 4.19

For kernel 5.13:HID_MULTITOUCH=m

Recommended virtual keyboard: xvkbd

Battery Monitor

Kernel .config



battery level in %:
cat /sys/class/power_supply/axp288_fuel_gauge/capacity
charger connected:
cat /sys/class/power_supply/axp288_charger/online
current from (or into) battery:
cat /sys/class/power_supply/axp288_fuel_gauge/current_now

App for X

Source code to display capacity and current continuously in X.


Working on kernel 5.13.5





cat in_accel_[xyz]_raw)

display does not tilt because Gnome too old (is 3.14, should be >= 3.18)


since 5.8
back VIDEO_ATOMISP_GC2235=m 
front VIDEO_ATOMISP_GC0310=m

kernel message about power gating failure.

Lid Switch


Triggers suspend.

Volume Button

The volume botton up/down and the button below it, but not the power button.


CPU temperature


Compile kernel


make -j3 INSTALL_MOD_STRIP=1 binrpm-pkg

Test protocol for c-state bug

Boot with USB-serial adapter and kernel parameter console=ttyUSB0,230400 clocksource=refined-jiffies.

During up to 2 shifts of 12 hours (up to 24 hours) run

4 instances of


in a directory containing 10 full HD videos of duration between 45 seconds and 2 minutes run this code:
for s in {1..1000}; do
  for f in *; do
    ffplay -loglevel panic -autoexit "$f"
    sleep 60


with internet connection via ethernet run
glances -s


in another PC run
glances -c @zx3040 -t 10

where zx3040 is the IP adress of the computer under test


via ssh run

with tab Idle stats

If no freeze is observed, the kernel is called good for the computer under test.

If a freeze is observed, the test must be repeated with intel_idle.max_cstate=1. If no freeze is observed the kernel is called bad for he computer under test. If a freeze is observed, there is a different bug, not a c-state bug 109051.

Blind Test

kernel-4.4.0 froze after 12h30m, up 2x13h with cstate=1.


ISO resulting from this build

To install this ISO into Linux:

mount android_x86_64.iso /mnt/x
cd /mnt/x
mkdir /android-x86
cp *.img system.sfs kernel /android-x86

To compile from source follow these steps:

Install repo utility

curl > ~/bin/repo
chmod a+x ~/bin/repo 

Get Android-x86

currently testing

edit ~/.jack-settings JACK_SERVER_VM_ARGUMENTS="-Dfile.encoding=UTF-8 -XX:+TieredCompilation -Xmx5g"
edit ~/.jack-server/ jack.server.max-service=1
mkdir android-x86
cd android-x86
repo init -u git:// -b oreo-x86 -m android-x86-8.1-r2.xml
repo sync --no-tags --no-clone-bundle 
rm -rf external/kernel-drivers/rtl* external/kernel-drivers/wl
cd  kernel
git remote add maurossi
git fetch maurossi kernel-5.3_si_next
git checkout FETCH_HEAD
make menuconfig KCONFIG_CONFIG=arch/x86/configs/android-x86_64_defconfig

Battery monitor

for stability change kernel config:


Kernel config




Copy firmware from to ../device/generic/firmware/intel.


According to!topic/android-x86/jc-AQFdk2gk

In Linux on target system use gnome-control-center to set maximum Speaker volume, then:
alsactl store -f
In Android build directory:
cp asound.state ../device/generic/common/alsa/bytcrrt5640.state

Move /data to sdcard

In order to save space in flash memory,

in ../device/generic/common/fstab.x86 insert as 2nd line:
/dev/block/mmcblk2p1    /data           ext4    noatime    defaults

and delete all lines containing mmc_*.


cd ..
export PATH=/usr/lib/jvm/java-1.8.0-openjdk/bin:/homelocal/elmar/android-x86/out/host/linux-x86/bin:/usr/lib/jvm/java-1.8.0-openjdk-$PATH:/usr/sbin
. build/
lunch android_x86_64-userdebug
m -j3 iso_img
cd out/target/product/x86_64
scp *.img system.sfs kernel <target_device>:/android-x86

Boot menu entry

menuentry "Android-x86" {
        linux /android-x86/kernel root=/dev/ram0 androidboot.selinux=permissive buildvariant=userdebug DATA=/data
        initrd /android-x86/initrd.img

User experience

  • booting the first time takes a very long time
  • setup wizard seems to take forever
  • touch screen ok
  • screen orientation ok
  • battery and charging indicator ok
  • wifi ok
  • sound ok
  • brightness ok!!
  • restart ok!!
  • rotate screen not working

Get root access

in terminal emulator do

modify system folder and remake system.sfs

cd out/target/product/android_x86_64 system /tmp/system.img ext4 system 0 -D system -L system root/file_contexts.bin
mksquashfs /tmp/system.img system.sfs -comp gzip

Copy and Install package

In Terminal Emulator do
cd /data
mkdir down
cd  down
ssh nome@host cat filename.apk > filename.apk
pm install -r filename.apk

Switch on/of fullscreen mode

In Terminal Emulator do
settings put global policy_control
settings put global policy_control


Start from a tinycore x86_64 instalation, for example

Remaster corepure64.gz

sudo mount TinyCorePure64-9.0.iso /mnt/x
cp /mnt/x/boot/corepure64.gz .
gunzip corepure64.gz 
mkdir corepure64_dir
cd corepure64_dir/
sudo cpio -id < ../corepure64
cd dev
sudo mknod mmcblk1 b 179 0
sudo mknod mmcblk1p1 b 179 1
sudo mknod mmcblk1p2 b 179 2
sudo mknod mmcblk1p2 b 179 3
sudo mknod mmcblk1p3 b 179 3
sudo mknod mmcblk2 b 179 24
sudo mknod mmcblk2p1 b 179 25
sudo mknod mmcblk2p2 b 179 26
sudo mknod mmcblk2p3 b 179 27
sudo chgrp ftp mmcblk*
sudo chmod ug+w mmcblk*
cd ..
cd lib/modules/
sudo cp -r /lib/modules/4.19.0-LAD .
cd ../..
find | sudo cpio -o -H newc > ../corepure64_4.19 
cd ..
gzip  corepure64_4.19 
sudo cp corepure64_4.19.gz /boot/

Create new menu entry in grub.cfg

menuentry 'Tinycore' --class gnu-linux --class gnu --class os {
        set gfxpayload=1024x768x16,1024x768
        linux /boot/vmlinuz-4.19.0-LAD root=LABEL=CentOS tce=mmcblk1p2 loglevel=3 vga=791 video=vesafb:ywrap,mtrr:3
        initrd /boot/corepure64_4.19.gz