Android x86 6.0 (마시멜로)에 VirtualBox Guest Additions을 설치하기 위한 여정을 담은 글입니다.
0. 왜 이런 뻘짓을?
Android-x86 guest의 마우스 움직임이 너무 답답하고, 어떻게든 상용 안드로이드 에뮬레이터처럼 그래픽 가속을 지원할 방법이 없을까 고민하다 직접 VirtualBox Guest Additions 관련 커널 모듈을 빌드하기로 마음먹었습니다.
결론부터 말씀드리면 3D 그래픽 가속은 실패했습니다. OpenGL 가속을 지원하는 UI Frontend를 직접 만들지 않는 한 불가능에 가까워보입니다. (지니모션, 녹스, LD플레이어 등등은 UI Frontend를 따로 만든 것으로 보입니다.)
ISO 이미지를 직접 빌드하면...
장점: Mouse integration. 한글 키보드 기본 포함.
단점: 매우 오랜 시간이 걸림. 이러나 저러나 3D 하드웨어 가속 안됨. MESA 라이브러리 빌드할 때 오류가 넘쳐남.
1. 준비물
Ubuntu: 가상머신도 가능합니다. 저는 VMWare Ubuntu 18.04로 진행했습니다.
OpenJDK 1.7: 현재 "apt-get install openjdk-7-jdk"으로 설치가 불가능하므로, 따로 tar.gz 파일을 구하셔야 합니다.
VirtualBox Guest Additions iso: https://download.virtualbox.org/virtualbox/ 참고하여 버전에 맞는 iso를 다운받으세요.
2. 우분투 환경설정
먼저 64비트 Ubuntu 18.04를 준비합니다.
먼저 settings > power > blank screen > Never로 설정해주셔야 불편함이 없습니다.
Android-x86 빌드 턱걸이 사양은 램 4기가 남짓 (4기가로 딱 맞추면 ninja 빌드 도중 터질 수 있음)
하드 용량은 적어도 120기가가 필요합니다. (소스 다운받고 나면 아마 105기가정도 차지할겁니다.)
추천 스펙은 램 6기가 이상, 하드 용량 200기가 이상입니다.
필요한 패키지들은 다음과 같습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
# Install packages
sudo apt -y install git gcc curl make repo libxml2-utils flex m4 lib32stdc++6 libelf-dev libssl-dev python-enum34 python-mako syslinux-utils libncurses-dev p7zip-full
# Git configuration
git config --global user.name "username"
git config --global user.email username@example.com
# Python configuration
sudo update-alternatives --install /usr/bin/python python /usr/bin/python2.7 1
sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.6 2
sudo update-alternatives --config python
# Java configuration
tar xvzf jdk-7u80-linux-x64.tar.gz
mv ./jdk1.7.0_80/ /usr/local/
cd /usr/local/jdk1.7.0_80/bin
./java -version # JAVA 1.7.0
vi /etc/profile.d/java.sh
export JAVA_HOME=/usr/local/jdk1.7.0_80
export JRE_HOME=/usr/local/jdk1.7.0_80/jre
export PATH=$JAVA_HOME/bin:$PATH
chmod +x /etc/profile.d/java.sh
source /etc/profile.d/java.sh
echo $JAVA_HOME # /usr/local/jdk1.7.0_80
|
cs |
3. Android x86 소스코드 다운로드
받아야 할 파일이 매우 많습니다. 100기가 이상의 여유공간이 있는지 확인하세요 [1].
중간중간 python 버전을 바꾸는게 언뜻 보기에 이상해보일텐데 일부 파이썬 코드는 2.x 기준으로 짜여져있고 일부 코드는 3.x를 기준으로 하고 있어서 스위칭을 해줘야 제대로 작동했습니다. 대환장파티네요.
1
2
3
4
5
6
7
|
mkdir home/username/android-x86
cd home/username/android-x86
sudo update-alternatives --config python 1
repo init -u git://git.osdn.net/gitroot/android-x86/manifest -b marshmallow-x86
sudo update-alternatives --config python 2
repo init -u git://git.osdn.net/gitroot/android-x86/manifest -b marshmallow-x86
repo sync --no-tags --no-clone-bundle
|
cs |
4. OpenJDK 체크 해제
자바 버전 및 OpenJDK 여부를 체크하는 부분이 있는데 가만히 놔두면 오류를 일으킵니다.
1.7.0 버전만 맞으면 빌드하는데 아무 문제가 없으므로 해당 부분을 삭제합니다.
1
2
3
4
5
6
7
8
9
|
************************************************************
You asked for an OpenJDK 7 build but your version is
java version "1.7.0_80" Java(TM) SE Runtime Environment (build 1.7.0_80-b15) Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode).
************************************************************
# Disable OpenJDK check
vi ./build/core/main.mk
# Search for 'requires_openjdk'
requires_openjdk := false
|
cs |
5. OpenGApps 설치
4번을 끝낸 상태에서 Android-x86 빌드를 시작하면 구글 플레이가 없는 채로 iso 이미지가 만들어집니다.
구글 플레이를 사용하려면 OpenGApps 설치가 필수적입니다 [2].
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
# Clone OpenGApps
vi ./.repo/manifests/default.xml
# Edit .repo/manifests/default.xml and add the following towards the end:
<remote name="opengapps" fetch="https://github.com/opengapps/" />
<remote name="opengapps-gitlab" fetch="https://gitlab.opengapps.org/opengapps/" />
<project path="vendor/opengapps/build" name="aosp_build" revision="master" remote="opengapps" />
<project path="vendor/opengapps/sources/all" name="all" clone-depth="1" revision="master" remote="opengapps-gitlab" />
<project path="vendor/opengapps/sources/x86" name="x86" clone-depth="1" revision="master" remote="opengapps-gitlab" />
<project path="vendor/opengapps/sources/x86_64" name="x86_64" clone-depth="1" revision="master" remote="opengapps-gitlab" />
repo sync --no-tags --no-clone-bundle --force-sync
# Download actual files from git lfs pointers
cd ./vendor/opengapps/sources/all
git lfs install
git lfs pull https://gitlab.opengapps.org/opengapps/all.git
cd ./vendor/opengapps/sources/x86
git lfs install
git lfs pull https://gitlab.opengapps.org/opengapps/x86.git
cd ./vendor/opengapps/sources/x86_64
git lfs install
git lfs pull https://gitlab.opengapps.org/opengapps/x86_64.git
cd ./vendor/opengapps/build
git lfs install
git lfs pull https://github.com/opengapps/aosp_build.git
# If you choose to add GAPPS, then edit file device/generic/common/device.mk and add at the beginning:
#OpenGAPPS
GAPPS_VARIANT := pico
GAPPS_PRODUCT_PACKAGES += Chrome \
KeyboardGoogle \
LatinImeGoogle \
GoogleTTS \
YouTube \
PixelIcons \
# PixelLauncher \ # Not working in Marshmallow-x86
Wallpapers \
# PixelLauncherIcons \ # Not working in Marshmallow-x86
WebViewGoogle \
GoogleServicesFramework \
GoogleLoginService \
GAPPS_FORCE_BROWSER_OVERRIDES := true
GAPPS_FORCE_PACKAGE_OVERRIDES := true
GAPPS_EXCLUDED_PACKAGES := FaceLock \
AndroidPlatformServices \
PrebuiltGmsCoreInstantApps \
# And at the end add:
#OpenGAPPS
$(call inherit-product, vendor/opengapps/build/opengapps-packages.mk)
# Edit android-x86 sources for XEN compatibility:
sed -i -e 's|/sys/block/\[shv\]d\[a-z\]|/sys/block/\[shv\]d\[a-z\] /sys/block/xvd\[a-z\]|g' bootable/newinstaller/install/scripts/1-install
sed -i -e 's|/sys/block/\[shv\]d\$h/\$1|/sys/block/\[shv\]d\$h/\$1 /sys/block/xvd\$h/\$1|g' bootable/newinstaller/install/scripts/1-install
sed -i -e 's|hmnsv|hmnsvx|g' bootable/newinstaller/initrd/init
# Configure kernel:
make -C kernel O=$OUT/obj/kernel ARCH=x86 menuconfig
# You need to edit these parameters:
XEN=yes
XEN_BLKDEV_BACKEND=yes
XEN_BLKDEV_FRONTEND=yes
XEN_NETDEV_BACKEND=no
XEN_NETDEV_FRONTEND=no
SECURITY_SELINUX_BOOTPARAM=yes
SECURITY_SELINUX_BOOTPARAM_VALUE=1
SECURITY_SELINUX_DISABLE=yes
DEFAULT_SECURITY_SELINUX=yes
|
cs |
6. VirtualBox Guest Additions 추가
당초 목표였던 Mouse integration을 위해 vboxguest.ko를 빌드합니다 [3, 4].
vboxsf.ko를 이용하면 호스트와 게스트 간의 공유폴더를 만들 수 있지만 안드로이드는 이미 ADB라는 강력한 툴이 있으므로 중요하지 않다고 봅니다.
마지막으로 vboxvideo.ko를 빌드할 경우 가상머신이 뻗어버리므로 제외합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
# Add VirtualBox Guest Additions
cd home/username/
git clone https://github.com/astsam/vboxsf.git
# You must copy Guest Additions (i.e., VBoxGuestAdditions_6.1.26.iso) to home/username/vboxsf/
# Use the script to add extra modules
./scripts/guest-copy VBoxGuestAdditions_6.1.26.iso /home/username/android-x86/
# Make sure to check home/username/android-x86/external/vboxsf/ is not empty
# Make sure to check home/username/android-x86/device/generic/x86/vboxguest/Android.mk exists
patch -p1 < /home/username/vboxsf/patches/marshmallow/mount-vbox-shared-folders.patch
patch -p1 < /home/username/vboxsf/patches/mouse-integration.patch
# Make sure every hunk successful
# Edit ./device/generic/x86/vboxguest/Makefile:
# Do not build vboxvideo.ko
obj-m = vboxguest/ vboxsf/ # vboxvideo/
# all: vboxguest vboxsf vboxvideo
all: vboxguest vboxsf
# .PHONY: vboxguest vboxsf vboxvideo all install clean check load
.PHONY: vboxguest vboxsf all install clean check load
# Copy ./device/generic/x86/vboxguest/Makefile to ./device/generic/x86_64/vboxguest/Makefile
cp ./device/generic/x86/vboxguest/Makefile ./device/generic/x86_64/vboxguest/
|
cs |
7. ISO 이미지 만들기
make후 python 관련 오류가 난다면 python 3.x로 먼저 시도후 python 2.x로 바꾸신 다음 다시 make 해보시기 바랍니다.
1
2
3
4
5
6
|
# Build ISO image
source build/envsetup.sh
lunch android_x86-userdebug
export BUILD_TARGET_ARCH=x86 # required to build vboxguest.ko
echo $BUILD_TARGET_ARCH # it should be 'x86'
make -j$( nproc --all ) iso_img
|
cs |
8. 트러블슈팅
7번에서 아무 문제없이 빌드를 성공했다면 아마 이 게시글을 작성하지 않았을지도 모릅니다.
헤더 파일이 없다고 하니 파이썬 파일을 이용하여 만들어줍니다.
그리고 헤더파일을 인식할 수 있도록 include directory 경로를 추가해줍니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
cd ./external/mesa/src/amd/common
python sid_tables.py sid.h > sid_tables.h
cd ./external/mesa/src/intel/genxml/
python gen_pack_header.py gen4.xml > gen4_pack.h
python gen_pack_header.py gen45.xml > gen45_pack.h
python gen_pack_header.py gen5.xml > gen5_pack.h
python gen_pack_header.py gen6.xml > gen6_pack.h
python gen_pack_header.py gen7.xml > gen7_pack.h
python gen_pack_header.py gen75.xml > gen75_pack.h
python gen_pack_header.py gen8.xml > gen8_pack.h
python gen_pack_header.py gen9.xml > gen9_pack.h
vi ./external/mesa/src/amd/Android.common.mk
LOCAL_C_INCLUDES := \
$(MESA_TOP)/include \
$(MESA_TOP)/src \
$(MESA_TOP)/src/amd/common \
$(MESA_TOP)/src/gallium/include \
$(MESA_TOP)/src/gallium/auxiliary \
$(intermediates)/common \
external/llvm/include \
external/llvm/device/include \
external/libcxx/include \
$(ELF_INCLUDES)
LOCAL_EXPORT_C_INCLUDE_DIRS := \
$(LOCAL_PATH)/common \
$(intermediates)/common
vi ./external/mesa/src/gallium/drivers/radeonsi/Android.mk
LOCAL_C_INCLUDES := \
$(MESA_TOP)/src/amd/common \
$(call generated-sources-dir-for,STATIC_LIBRARIES,libmesa_amd_common,,)/common
LOCAL_EXPORT_C_INCLUDE_DIRS := \
$(LOCAL_PATH)/common \
$(intermediates)/common
|
cs |
에러 하나로 끝나면 좋으련만...
변수가 정의되지 않았다네요. 문제가 되는 부분 주석처리합니다.
1
2
3
4
5
6
7
8
9
|
vi ./packages/apps/PackageInstaller/src/com/android/packageinstaller/permission/ui/OverlayTouchActivity.java
// import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
/*
@Override
protected void onCreate(Bundle savedInstanceState) {
getWindow().addPrivateFlags(PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
super.onCreate(savedInstanceState);
}
*/
|
cs |
저는 오류 2개 해결한 이후 빌드 성공하였습니다.
빌드에 성공하면 android_x86.iso가 만들어지며 용량이 대략 840~850MB 이어야 구글플레이가 포함된겁니다.
구글플레이가 없는 경우 iso 용량이 대략 340MB 였습니다.
다른 에러가 발생하실 경우 [5]에 매우 잘 설명되어있으니 참고하시기 바랍니다.
9. 참고문헌
[1] Android-x86 Get Source, https://www.android-x86.org/source.html
[2] Android-x86 7.1-r2 with GAPPS installation guide, https://groups.google.com/g/qubes-users/c/HGAT6DmuQkM
[3] Roger Ye, Android System Programming.
[4] Utility for Android to mount VirtualBox shared folders, https://github.com/astsam/vboxsf
[5] Android-x86-6.0 Customization Road-Compile on Ubuntu 16.04.5, https://blog.csdn.net/Ctrl_S/article/details/88669461