手里就一台笔记本,可不想把系统换成Linux的,毕竟有很多操作还是很不方便,但是又想学习学习Android源码,所以,总得找点什么凑活着用的办法,于是我把目光放到了Win10上的Linux子系统上了,也就是WSL,毕竟虚拟机太废内存划不来,亲测
CPU:AMD Ryzen 7 4800H with Radeon Graphics 2.90 GHz
RAM:16G
ROM:512G SSD + 2T HDD
GPU:GTX 1650
跑起来不说多么流畅,反正不卡,可能编译慢点,咱也不差那点时间,硬盘预留个256G的空间就够了。话不多说,记录一下这次操作的经历..
1 安装WSL2 网上教程比较多,直接看微软官方教程即可:[在 Windows 10 上安装 WSL | Microsoft Docs](在 Windows 10 上安装 WSL | Microsoft Docs )
我这里按照教程装了Ubuntu-18.04,推荐也安装个Windows Terminal,还是挺好用的,可以看看这个:Windows Terminal 完美配置 PowerShell 7.1 - 知乎 (zhihu.com)
按照这个方法安装完了呢,WSL2所有东西都是默认放在C盘的,咱可是要做大事的人,C盘怕是放不太下,啥?你就一个盘,好的,当我没说。
1.1 WSL2挪位 我C盘就200G显然不能够干大事,所以就转移到E盘了,于是,咱们打开powershell或者Windows Terminal:
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 PS C:\Users\Sidney\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu18.04 onWindows_79rhkp1fndgsc\LocalState> cd ~PS C:\Users\Sidney> wsl --shutdown PS C:\Users\Sidney> wsl -l -v NAME STATE VERSION * Ubuntu-18 .04 Stopped 2 PS C:\Users\Sidney> wsl --export Ubuntu-18 .04 E:\wsl2\ubuntu18\ubuntu18.tarPS C:\Users\Sidney> wsl --unregister Ubuntu-18 .04 PS C:\Users\Sidney> wsl --import Ubuntu-18 .04 E:\wsl2\ubuntu18 E:\wsl2\ubuntu18\ubuntu18.tarPS C:\Users\Sidney> ubuntu1804.exe config --default-user sidneyPS C:\Users\Sidney> $newLocation = "E:\wsl2\ubuntu18" PS C:\Users\Sidney> cd ~\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu18.04 onWindows_79rhkp1fndgsc\LocalStatePS C:\Users\Sidney\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu18.04 onWindows_79rhkp1fndgsc\LocalState> wsl --shutdown PS C:\Users\Sidney\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu18.04 onWindows_79rhkp1fndgsc\LocalState> Optimize-VHD .\ext4.vhdx -Mode FullPS C:\Users\Sidney\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu18.04 onWindows_79rhkp1fndgsc\LocalState> mkdir $newLocation -Force PS C:\Users\Sidney\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu18.04 onWindows_79rhkp1fndgsc\LocalState> mv ext4.vhdx $newLocation PS C:\Users\Sidney\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu18.04 onWindows_79rhkp1fndgsc\LocalState> cd ..PS C:\Users\Sidney\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu18.04 onWindows_79rhkp1fndgsc\LocalState> rm LocalStatePS C:\Users\Sidney\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu18.04 onWindows_79rhkp1fndgsc\LocalState> New-Item -ItemType SymbolicLink -Path "LocalState" -Target $newLocation
至此已经完成了wsl的迁移,已经可以用了
贴两张图
一个是 启用或关闭Windows功能,Win + R
– 输入”control”,回车 – 程序
另一个是 服务,Win + R
– 输入”services.msc”,回车
接下来需要考虑一件事,把Android源码放在哪?如果放在宿主机,Win10上,最好开启大小写敏感,以及得考虑后面权限的事情,我怕麻烦,最后决定就放wsl里面好了
1 2 3 4 5 6 fsutil file SetCaseSensitiveInfo E:\workspace\AOSP enable fsutil file SetCaseSensitiveInfo E:\workspace\CCACHE enable fsutil file SetCaseSensitiveInfo E:\workspace\AOSP disable fsutil file SetCaseSensitiveInfo E:\workspace\CCACHE disable
如果想要看代码,可以在wsl里面再弄个opengrok:Build OpenGrok To Read the Fuck Source Code | Sidney God
1.2 WSL2配置 我也是后来才想起来的,这儿么点配置,编译Android有点费事不说,还有可能编不了,我们需要对wsl做点什么:Manage Linux Distributions | Microsoft Docs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 PS C:\Users\Sidney> vim ~\.wslconfig[wsl2 ] processors=4 swap=16 GB swapFile=%USERPROFILE%\AppData\Local\Temp\swap.vhdx localhostForwarding=true [int erop ] enabled=false appendWindowsPath=false PS C:\Users\Sidney> wsl --shutdown net stop LxssManager net start LxssManager
1.3 WSL2扩容 WSL2使用虚拟硬件磁盘(VHD)来存储Linux文件。如果达到其最大大小,则可能需要对其进行扩展。WSL2 VHD使用ext4文件系统,此VHD会自动调整大小以满足你的存储需求,并且其最大大小为256GB。如果你的分发版大小增长到大于256GB,则会显示错误,指出磁盘空间不足。 可以通过扩展 VHD 大小来纠正此错误。若要将最大 VHD 大小扩展到超过 256GB,请执行以下操作:
以管理员模式打开powershell
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 PS C:\WINDOWS\system32> diskpartMicrosoft DiskPart 版本 10.0 .19041.964 Copyright (C) Microsoft Corporation. 在计算机上: SIDNEYGOD DISKPART> list vol 卷 ---------- --- ----------- ----- ---------- ------- --------- -------- 卷 0 E Data NTFS 磁盘分区 1863 GB 正常 卷 1 C System NTFS 磁盘分区 200 GB 正常 启动 卷 2 D Software NTFS 磁盘分区 275 GB 正常 卷 3 SYSTEM_DRV FAT32 磁盘分区 260 MB 正常 系统 卷 4 WINRE_DRV NTFS 磁盘分区 1000 MB 正常 已隐藏 DISKPART> list vdisk 没有要显示的虚拟磁盘。 DISKPART> Select vdisk file="E:\wsl2\ubuntu18\ext4.vhdx" DISKPART> expand vdisk maximum="358400" DISKPART> exit
1.4 WSL2压缩 上面扩容完了有时候又会觉得分的太大,浪费,又想收回来,所以又得要个压缩空间的法子,同样是管理员模式打开powershell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 # 关闭wsl wsl.exe --shutdown # 查看当前子系统是不是在stopped状态 wsl.exe --list --verbose # 进入磁盘管理 diskpart # 选中要操作的虚拟磁盘 select vdisk file="E:\wsl2\ubuntu18\ext4.vhdx" # 压缩 compact vdisk # 等一会 100 百分比已完成 # 退出 exit
到这里算是把wsl折腾完了
2 编译Android 我这里为啥没选Android S呢,完全是因为编不懂,编system的时候总是segment fault,并且当时也忘了设置swap试试,所以就试试Android R了,结果还是比较满意的
2.1 prepare Ubuntu换源,基础的东西装一下。首先,Java得要安装吧,百度一下
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 sudo mv /etc/apt/sources.list /etc/apt/sources.list.bak sudo vim /etc/apt/sources.list deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse deb http://us.archive.ubuntu.com/ubuntu/ xenial main universe deb-src http://us.archive.ubuntu.com/ubuntu/ xenial main universe sudo apt update sudo apt upgrade sudo add-apt-repository ppa:linuxuprising/java sudo apt update apt list | grep oracle-java sudo apt install oracle-java17-installer sudo apt install oracle-java17-set-default
然后git配置一下,我发现这个git是有缺陷的,有需要最好重新安装一下
然后把Android编译需要的东西安装一下
1 2 3 4 5 sudo apt-get install gcc python bc git-core gnupg flex bison gperf libsdl1.2-dev \ libesd0-dev squashfs-tools build-essential zip curl \ libncurses5-dev zlib1g-dev pngcrush schedtool libxml2 libxml2-utils \ xsltproc lzop libc6-dev schedtool g++-multilib lib32z1-dev lib32ncurses5-dev \ lib32readline6-dev gcc-multilib libswitch-perl libssl1.0.0 libssl-dev
查询想要下载的分支:https://android.googlesource.com/platform/manifest/+refs,需要翻墙能力,或者用github也行:[aosp-mirror/platform_manifest (github.com)](https://github.com/aosp-mirror/platform_manifest )
我最终选的是android11-release
2.2 Compile AOSP 这里主要参考了:https://gitee.com/SidneyGod/ImagePlace/blob/master/attachments/exercises-210203.pdf
关于Android源码的下载,由于墙的原因,必然只能找镜像的,清华源,北外源,中科大源都是ok的
AOSP | 镜像站使用帮助 | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror
AOSP | 镜像站使用帮助 | 北京外国语大学开源软件镜像站 | BFSU Open Source Mirror
AOSP 镜像使用帮助 — USTC Mirror Help 文档
建议repo啥的,直接都用这些源提供的就好
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 curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo -o repo chmod +x repomkdir -p ~/FuckSourceCode/1-android11-releasecd ~/FuckSourceCode/1-android11-releaserepo init -u git://mirrors.ustc.edu.cn/aosp/platform/manifest -b android11-release --depth=1 --no-tags repo sync -j4 --fail-fast --force-sync source build/envsetup.shlunch aosp_x86_64-eng make -j4 sidney@SidneyGod:~/FuckSourceCode/1-android11-release$ ls out/target/product/generic_x86_64/ -la total 6757124 drwxr-xr-x 20 sidney sidney 4096 Jun 12 22:07 . drwxr-xr-x 3 sidney sidney 4096 Jun 6 17:00 .. -rw-r--r-- 1 sidney sidney 356 Jun 12 22:07 VerifiedBootParams.textproto -rw-r--r-- 1 sidney sidney 383 Jun 6 17:06 advancedFeatures.ini -rw-r--r-- 1 sidney sidney 18874368 Jun 6 17:06 encryptionkey.img -rw-r--r-- 1 sidney sidney 14157728 Jun 12 22:03 kernel-ranchu -rw-r--r-- 1 sidney sidney 2927776 Jun 12 22:03 ramdisk-qemu.img drwxr-xr-x 15 sidney sidney 4096 Jun 12 22:05 system -rw-r--r-- 1 sidney sidney 3232759808 Jun 12 22:08 system-qemu.img -rw-r--r-- 1 sidney sidney 576716800 Jun 12 22:03 userdata.img -rw-r--r-- 1 sidney sidney 68157440 Jun 12 22:05 vendor-qemu.img
编译完了当然要看看咱们的成果了,由于咱是在WSL里面弄的,肯定不能敲一个emulator命令了事
首先,它需要一个模拟器,去下载Android Studio并且创建一个模拟器,这一部不详细说了
比如我这里创建的模拟器和下载的image是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 PS C:\Users\Sidney> emulator -list-avds Pixel_3_Edited_API_30 PS C:\Users\Sidney> ls D:\Develop\Environments\sdk\system-images \android-30 \google_apis\x86_64\ 目录: D:\Develop\Environments\sdk\system-images \android-30 \google_apis\x86_64 Mode LastWriteTime Length Name ---- ------------- ------ ---- d----- 2021 /6 /7 22 :09 data -a---- 2021 /6 /12 22 :08 383 advancedFeatures.ini-a---- 2021 /6 /12 22 :08 2271 build.prop-a---- 2021 /6 /12 22 :08 18874368 encryptionkey.img-a---- 2021 /6 /12 22 :08 14157728 kernel-ranchu -a---- 2021 /6 /7 22 :09 2984443 NOTICE.txt-a---- 2021 /6 /7 22 :09 18153 package.xml-a---- 2021 /6 /12 22 :08 2927776 ramdisk.img-a---- 2021 /6 /7 22 :09 294 source.properties-a---- 2021 /6 /12 22 :08 3232759808 system.img-a---- 2021 /6 /12 22 :08 576716800 userdata.img-a---- 2021 /6 /12 22 :08 68157440 vendor.img-a---- 2021 /6 /12 22 :08 356 VerifiedBootParams.textproto
可以看到核心也就这么几个文件,把这些文件备份一下,拷入我们编译出来的image
1 2 3 4 5 6 7 8 9 10 11 12 13 14 cp out/target/product/generic_x86_64/VerifiedBootParams.textproto /mnt/d/Develop/Android/MySystemImg/cp out/target/product/generic_x86_64/advancedFeatures.ini /mnt/d/Develop/Android/MySystemImg/cp out/target/product/generic_x86_64/encryptionkey.img /mnt/d/Develop/Android/MySystemImg/cp out/target/product/generic_x86_64/kernel-ranchu /mnt/d/Develop/Android/MySystemImg/cp out/target/product/generic_x86_64/ramdisk-qemu.img /mnt/d/Develop/Android/MySystemImg/ramdisk.imgcp out/target/product/generic_x86_64/system-qemu.img /mnt/d/Develop/Android/MySystemImg/system.imgcp out/target/product/generic_x86_64/userdata.img /mnt/d/Develop/Android/MySystemImg/cp out/target/product/generic_x86_64/vendor-qemu.img /mnt/d/Develop/Android/MySystemImg/vendor.imgcp out/target/product/generic_x86_64/system/build.prop /mnt/d/Develop/Android/MySystemImg/emulator -avd Pixel_3_Edited_API_30 -writable-system -wipe-data -show-kernel -skip-adb-auth -no-cache
看一下,效果还是可以的
只不过这里的kernel其实是源码里自带的,没有源码,所以略显僵硬,注意这里的内核版本
1 2 3 C:\Users\Sidney>adb shell generic_x86_64:/ # cat /proc/version Linux version 5.4.47-01061-g22e35a1de440 (android-build@abfarm-east4-070) (Android (6443078 based on r383902) clang version 11.0.1 (https://android.googlesource.com/toolchain/llvm-project b397f81060ce6d701042b782172ed13bee898b79), LLD 11.0.1 (/buildbot/tmp/tmp6_m7QH b397f81060ce6d701042b782172ed13bee898b79)) #1 SMP PREEMPT Fri Jun 19 01:58:49 UTC 2020
下面继续整个内核源码
2.3 Compile Kernel 貌似从Android11开始,内核整了个gki,Android 通用内核 | Android 开源项目 | Android Open Source Project (google.cn)
关于内核的版本我选择了与参考文档不一样的版本,不是common-android11-5.4,而是common-android-mainline,毕竟根据Android官方文档介绍,common-android-mainline看起来才是祖宗,于是乎
1 2 3 4 sidney@SidneyGod:~/FuckSourceCode$ mkdir 2-common-android-mainline sidney@SidneyGod:~/FuckSourceCode$ cd 2-common-android-mainline sidney@SidneyGod:~/FuckSourceCode/2-common-android-mainline$ repo init -u http://mirrors.tuna.tsinghua.edu.cn/git/AOSP/kernel/manifest -b common-android11-5.4 --depth=1 sidney@SidneyGod:~/FuckSourceCode/2-common-android-mainline$ repo sync -j4
代码下载完成后,并不能直接进行编译,而是需要改一个地方
1 2 3 4 5 6 7 8 9 10 11 12 13 14 sidney@SidneyGod:~/FuckSourceCode/2-common-android-mainline$ cd common sidney@SidneyGod:~/FuckSourceCode/2-common-android-mainline/common$ git diff @@ -1,5 +1,5 @@ CONFIG_LOCALVERSION="-mainline" -CONFIG_KERNEL_LZ4=y +CONFIG_KERNEL_BZIP2=y # CONFIG_USELIB is not set CONFIG_AUDIT=y CONFIG_NO_HZ=y
貌似是因为Ubuntu18不支持LZ4打包,改成BZIP2就可以了,于是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 sidney@SidneyGod:~/FuckSourceCode/2-common-android-mainline$ SKIP_MRPROPER=1 BUILD_CONFIG=common/build.config.gki.x86_64 build/build.sh sidney@SidneyGod:~/FuckSourceCode/2-common-android-mainline$ SKIP_MRPROPER=1 BUILD_CONFIG=common-modules/virtual-device/build.config.virtual_device.x86_64 build/build.sh sidney@SidneyGod:~/FuckSourceCode/2-common-android-mainline$ cd ../1-android11-release sidney@SidneyGod:~/FuckSourceCode//1-android11-release$ cp prebuilts/qemu-kernel/x86_64/5.4 prebuilts/qemu-kernel/x86_64/5.4.bak sidney@SidneyGod:~/FuckSourceCode/1-android11-release$ cd ../2-common-android-mainline sidney@SidneyGod:~/FuckSourceCode/2-common-android-mainline$ rm -rf ../1-android11-release/prebuilts/qemu-kernel/x86_64/5.4/kernel-qemu2 sidney@SidneyGod:~/FuckSourceCode/2-common-android-mainline$ rm -rf ../1-android11-release/prebuilts/qemu-kernel/x86_64/5.4/ko/* sidney@SidneyGod:~/FuckSourceCode/2-common-android-mainline$ cp out/android-mainline/dist/bzImage /home/sidney/FuckSourceCode/1-android11-release/prebuilts/qemu-kernel/x86_64/5.4/kernel-qemu2 sidney@SidneyGod:~/FuckSourceCode/2-common-android-mainline$ out/android-mainline/dist/*.ko /home/sidney/FuckSourceCode/1-android11-release/prebuilts/qemu-kernel/x86_64/5.4/ko/ sidney@SidneyGod:~/FuckSourceCode/2-common-android-mainline$ cd ../1-android11-release sidney@SidneyGod:~/FuckSourceCode/1-android11-release$ make -j4
最后的步骤当然和前面的一摸一样了,把编译出来的image拷贝到宿主机中
1 2 3 4 5 6 7 8 9 10 11 12 13 cp out/target/product/generic_x86_64/VerifiedBootParams.textproto /mnt/d/Develop/Android/MySystemImg/cp out/target/product/generic_x86_64/advancedFeatures.ini /mnt/d/Develop/Android/MySystemImg/cp out/target/product/generic_x86_64/encryptionkey.img /mnt/d/Develop/Android/MySystemImg/cp out/target/product/generic_x86_64/kernel-ranchu /mnt/d/Develop/Android/MySystemImg/cp out/target/product/generic_x86_64/ramdisk-qemu.img /mnt/d/Develop/Android/MySystemImg/ramdisk.imgcp out/target/product/generic_x86_64/system-qemu.img /mnt/d/Develop/Android/MySystemImg/system.imgcp out/target/product/generic_x86_64/userdata.img /mnt/d/Develop/Android/MySystemImg/cp out/target/product/generic_x86_64/vendor-qemu.img /mnt/d/Develop/Android/MySystemImg/vendor.imgcp out/target/product/generic_x86_64/system/build.prop /mnt/d/Develop/Android/MySystemImg/emulator -avd Pixel_3_Edited_API_30 -writable-system -wipe-data -show-kernel -skip-adb-auth -no-cache
再上效果图
再看看这里的内核版本
1 2 3 C:\Users\Sidney>adb shell generic_x86_64:/ Linux version 5.13.0-rc5-mainline-g9c2efcb127bb-dirty (build-user@build-host) (Android (7284624, based on r416183b) clang version 12.0.5 (https://android.googlesource.com/toolchain/llvm-project c935d99d7cf2016289302412d708641d52d2f7ee), LLD 12.0.5 (/buildbot/src/android/llvm-toolchain/out/llvm-project/lld c935d99d7cf2016289302412d708641d52d2f7ee))
到这里就说明成功了,至此,kernel和system都可以顺利编译了
另外,如果拷贝完image到宿主机后,发现无法开机,并报下面的错,那可能是image没编好,kernel不适配,重新整编一下就好了
1 2 3 4 5 6 7 8 9 [ 1.785501 ] init: Failed to insmod '/lib/modules/dummy-cpufreq.ko' with args '' [ 1.789747 ] init: LoadWithAliases was unable to load dummy_cpufreq [ 1.793175 ] init: [libfs_mgr]ReadFstabFromDt(): failed to read fstab from dt [ 1.797138 ] init: Using Android DT directory /proc /device-tree/firmware/android/ [ 1.824079] init: bool android::init::BlockDevInitializer::InitDevices(std::set<std::string>): partition(s) not found in /sys, waiting for their uevent(s): metadata, super, vbmeta [ 11.844727] init: Wait for partitions returned after 10011ms [ 11.848915] init: bool android::init::BlockDevInitializer::InitDevices(std::set<std::string>): partition(s) not found after polling timeout: metadata, super, vbmeta [ 11.855918] init: Failed to mount required partitions early ... [ 11.859722] init: InitFatalReboot: signal 6
Android12编译后起不来 首先AndroidS和AndroidR的操作基本没啥区别,只不过lunch时候的选项可能需要改一下,因为用aosp_x86_64-eng
编译完成后没有qemu的image和userdata.img
,就像stack overflow上这样android 12 latest release: Emulator build not running for android-12.0.0_r2 aosp release - Stack Overflow
1 Error: out/target/product/generic_arm64/userdata-qemu.img': No such file or directory
解决方案我也贴上去了,就是需要在build/make/target/product/AndroidProducts.mk
下面加一句
1 2 3 4 5 6 7 8 9 @@ -84,3 +84,4 @@ COMMON_LUNCH_CHOICES := \ aosp_arm-eng \ aosp_x86_64-eng \ aosp_x86-eng \ + sdk_phone_x86_64-eng \
然后lunch的时候选择sdk_phone_x86_64-eng
就好了..
Android12 kernel无效 Android12的kernel不在prebuilts/qemu-kernel/x86_64/
,这里面也没有5.10,而是在
kernel/prebuilts/5.10/x86_64/kernel-5.10
和kernel/prebuilts/common-modules/virtual-device/5.10/x86-64/*.ko
,对应的bzImage和ko文件挪到这里就好了,注意不要把bp文件给删了