修改Android内核和源码使lxc和Docker成功的运行——基于Lineage OS 21 (Android 14)
事情的起因
故事要从我的电子设备说起。
我的电脑是败家之眼幻14,虽然从外观上来看起始幻14并不是传统的游戏本,与外形夸张的游戏本相比,我其实更喜欢稍微内敛一些但是性能也比较够用的全能本系列。不过这就带来了一个问题:背着这玩意通勤实在是一件令人浑身难受的事情。每天当我看到室友拿着一台13寸的轻薄本和一个100w氮化镓就去上课,再看看我这台沉的一批的笔记本,我陷入了沉默。在无数个夜晚我都在想,如果上大学的时候我买的是轻薄本,那我如今该多么快乐啊!可惜世上并没有回头路了。
在大学待了一年之后,在各种机缘巧合和需求下,我购置了一台平板,三星 tab s6 lite,虽说配置不是很高,exynos 9610,4GB的内存,64GB的硬盘,但1500多的价格让我感觉这玩意是真tm实惠, 在体验了一年的OneUI之后,我最终还是决定将这台机器root掉刷成Lineage OS。虽然我失去了三星原生的笔记应用(很幸运,笔是可以正常用的),但同时我收获了更长的续航,更快的响应速度,以及更加自由的环境。在这时,一个突然的想法在我脑海中产生了:为什么不给这个板子搞一个Linux环境出来呢?
选择lxc的原因
有了想法之后,首先我开始选型。玩过多年Linux和Android的我了解的在一个Linux中运行另一个Linux环境的方法有如下几种:
方法 | 描述 | 优点 | 缺点 | 示例 |
---|---|---|---|---|
chroot | 最简单的容器化,只是将运行环境的root切换为了新的root | 所有Linux(不管SysV,systemd,OpenRC还是run-parts)都支持 | 环境隔离不是很充分,而且不能运行独立的init | 在Android下最简单的Linux环境就是用这个搭的(Linux Deploy) |
proot | 同上,但是不需要root权限 | 不需要root权限,所以不用解锁bootloader就可以愉快玩耍 | 性能会有所下降,而且很容易被杀 | 网络上大部分教程使用Termux运行Linux环境的都是这个 |
systemd-nspawn | 模拟了cgroup等环境,然后运行guest的systemd进程 | systemd自带,使用很方便 | 只支持使用systemd的host和guest | 我用来编译Android的Debian环境就是这么启的 |
lxc | 模拟cgroup等环境,然后运行guest的init进程 | 对systemd没有依赖,而且lxc比较成熟,提供了检查内核配置是否可以运行lxc的工具 | 要求有点多,在Adnroid上不太好实现,需要修改内核 | maru os就是用lxc实现的启动Linux环境 |
docker | 模拟环境后,根据Dockerfile中的endpoint执行程序进程 | 用来起应用非常方便,并没有对systemd的强依赖 | 实在是有些臃肿,而且并不适合做系统容器,并且需要修改内核 | 做项目的时候会用到(写一个docker-compose然后拜托它帮我起服务) |
kvm/qemu | 模拟一个完整的虚拟机环境,运行一个独立的Linux内核 | 环境隔离最完善最安全,且不拘泥于运行Linux | 需要运行另一个内核,性能有损耗,在Android设备上基本没有支持(只有一些魔改内核和Google Tencor支持,估计支持会越来越多,但目前还不行) | 一般需要Windows环境的时候会起一个kvm(我电脑上没有Windows) |
在几年前,我最开始接触在Android上运行Linux环境的时候使用的是chroot。当时Linux Deploy对我来说是非常惊艳的,但随后我就遇到了一些问题。因为我熟悉的系统(Debian,Ubuntu,Manjaro等)都是依赖systemd的系统,在非systemd环境中就会或多或少的存在一些问题,虽然Debian等系统在没有systemd的时候会尝试着使用SysV模式,但某些工具(比如cockpit等)并不能很好的支持非systemd环境。于是,我将目光转移到了lxc上(Docker同理,需要的配置很相似)。
内核,源码处理
既然选择走向了lxc这条道路,那么编译内核和系统就是逃不过的问题了。相比于在系统中安装大量不必要的软件包,我更倾向于使用一个容器来解决打包的问题。在Linux下构建一个Ubuntu或Debian容器是很简单的一件事情,你只需要在本级的Linux中安装debootstrap
软件包,然后指定一定的参数(具体使用方法请自行Google),即可在目录下生成一个完整的rootfs,然后你就可以使用chroot
或者systemd-nspawn
来启动这个容器了。对我来说,除了启动容器,我还需要做一些配置操作,于是我写了一个脚本(其实是三个脚本合在一起)帮助我完成这一任务。以下是我脚本的内容,仅供参考:
setupenv.sh(脚本入口,依赖下面两个脚本,执行时请sudo):
#!/bin/sh
#获取脚本所在文件夹
dir_root=`dirname $0`
#指定rootfs所在文件夹,我这里指定的是“脚本所在文件夹/build_environment_x64”
build_root=$dir_root/build_environment_x64
export REPO_URL='https://mirrors.tuna.tsinghua.edu.cn/git/git-repo'
#mount system informations for chroot
#mount --bind /proc $build_root/proc
#mount --bind /dev $build_root/dev
#mount --bind /sys $build_root/sys
#mount --bind /dev/pts $build_root/dev/pts
#mount build files
#挂载home目录,你用户名叫啥你就挂在哪
mount --bind $dir_root $build_root/home/zhangke200377/
#我额外挂了一个分区到我的家目录里,装rootfs的分区有点不够大
mount /dev/sda3 $dir_root/lineage02
#start systemd-nspawn
sh ./enterenv.sh
#clean up
sh ./cleanup.sh
enterenv.sh:
#!/bin/sh
dir_root=`dirname $0`
build_root=$dir_root/build_environment_x64
#for chroot:chroot $build_root
systemd-nspawn -b -D $build_root
cleanup.sh
#!/bin/sh
dir_root=`dirname $0`
build_root=$dir_root/build_environment_x64
#clean up for chroot
#umount -v $build_root/proc
#umount -v $build_root/dev/pts
#umount -v $build_root/dev
#umount -v $build_root/sys
umount -v $dir_root/lineage02
umount -v $build_root/home/zhangke200377/
启动容器后,前往lineage os的wiki中找到你的设备,跟随build for yourself
的指引先整编一个原版的系统(主要是为了排错),然后刷入你的机器中(修改的版本和原版其实没差多少,所以提前刷一个原版以防之后出现奇奇怪怪的错误,也方便有问题现在就处理,多种可能造成的问题是最难以排除的,所以控制一下变量对自己有好处),如果你的设备并没有官方支持,你也可以去xda forums
查找你的设备是否有unofficial支持,并根据维护者给出的源码地址自行修改源码文件夹中.repo/local_manifests/roomservice.xml
的文件内容(没有的可以自己新建一个)。我自己的roomservice.xml内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
<project path="device/samsung/gta4xlwifi" remote="github" name="linux4-bringup-priv/android_device_samsung_gta4xlwifi" revision="lineage-21.0" />
<project path="device/samsung/gta4xl-common" remote="github" name="linux4-bringup-priv/android_device_samsung_gta4xl-common" revision="lineage-21.0" />
<project path="device/samsung_slsi/sepolicy" remote="github" name="linux4-bringup-priv/android_device_samsung_slsi_sepolicy" revision="lineage-21.0" />
<project path="hardware/samsung" remote="github" name="linux4-bringup-priv/android_hardware_samsung" revision="lineage-21.0" />
<project path="hardware/samsung_slsi/libbt" remote="github" name="linux4-bringup-priv/android_hardware_samsung_slsi_libbt" revision="lineage-21.0" />
<project path="hardware/samsung_slsi-linaro/config" remote="github" name="linux4-bringup-priv/android_hardware_samsung_slsi-linaro_config" revision="lineage-21.0" />
<project path="hardware/samsung_slsi-linaro/exynos" remote="github" name="linux4-bringup-priv/android_hardware_samsung_slsi-linaro_exynos" revision="lineage-21.0" />
<project path="hardware/samsung_slsi-linaro/exynos5" remote="github" name="linux4-bringup-priv/android_hardware_samsung_slsi-linaro_exynos5" revision="lineage-21.0" />
<project path="hardware/samsung_slsi-linaro/graphics" remote="github" name="linux4-bringup-priv/android_hardware_samsung_slsi-linaro_graphics" revision="lineage-21.0" />
<project path="hardware/samsung_slsi-linaro/openmax" remote="github" name="linux4-bringup-priv/android_hardware_samsung_slsi-linaro_openmax" revision="lineage-21.0" />
<project path="hardware/samsung_slsi/scsc_wifibt/wifi_hal" remote="github" name="linux4-bringup-priv/android_hardware_samsung_slsi_scsc_wifibt_wifi_hal" revision="lineage-21.0" />
<project path="hardware/samsung_slsi/scsc_wifibt/wpa_supplicant_lib" remote="github" name="linux4-bringup-priv/android_hardware_samsung_slsi_scsc_wifibt_wpa_supplicant_lib" revision="lineage-21.0" />
<project path="kernel/samsung/gta4xl" remote="github" name="linux4-bringup-priv/android_kernel_samsung_gta4xl" revision="lineage-21.0" />
<project path="hardware/samsung_slsi-linaro/interfaces" remote="github" name="linux4-bringup-priv/android_hardware_samsung_slsi-linaro_interfaces" revision="lineage-21.0" />
<project path="vendor/samsung/gta4xl-common" remote="github" name="linux4-bringup-priv/android_vendor_samsung_gta4xl-common" revision="lineage-21.0" />
<project path="vendor/samsung/gta4xlwifi" remote="github" name="linux4-bringup-priv/android_vendor_samsung_gta4xlwifi" revision="lineage-21.0" />
</manifest>
然后执行一遍repo sync --no-clone-bundle
即可正常的进入编译流程了。
在整编完成之后,即可对内核和系统进行修改。
首先是内核,内核主要动两个部分,一个是内核的配置文件,需要打开SYSV_IPC
等一系列的开关,以便lxc可以正常的工作。另一个是要修改cgroups的挂载代码,这部分其实有两种修改办法,即在不同位置挂载两份和修改现有的挂载点,不过为了防止Android中的某些东西可能会触发一些不确定的问题,我还是选择了挂载两份,毕竟也不占空间,挂就挂了能咋的🤪。内核的修改我直接放一个diff出来,大家根据自己的实际情况修改即可,可能会发生某些文件找不到的情况(实际上必然会发生,如果你的机型不是gta4xlwifi的话),请随本心进行修改(毕竟我也不知道你的机型是什么),或者实在不行就手工应用diff嘛[doge]。
kernel.diff
diff --git a/arch/arm64/configs/exynos9611-gta4xlwifi_defconfig b/arch/arm64/configs/exynos9611-gta4xlwifi_defconfig
index 9f8f533f9efd..9c449a438cab 100644
--- a/arch/arm64/configs/exynos9611-gta4xlwifi_defconfig
+++ b/arch/arm64/configs/exynos9611-gta4xlwifi_defconfig
@@ -50,10 +50,11 @@ CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_DEFAULT_HOSTNAME="(none)"
CONFIG_SWAP=y
-# CONFIG_SYSVIPC is not set
+CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
CONFIG_CROSS_MEMORY_ATTACH=y
-# CONFIG_FHANDLE is not set
+CONFIG_FHANDLE=y
+CONFIG_POSIX_MQUEUE=y
# CONFIG_USELIB is not set
CONFIG_AUDIT=y
CONFIG_HAVE_ARCH_AUDITSYSCALL=y
@@ -139,25 +140,28 @@ CONFIG_MEMCG_SWAP=y
CONFIG_MEMCG_SWAP_ENABLED=y
CONFIG_MEMCG_FORCE_USE_VM_SWAPPINESS=y
CONFIG_BLK_CGROUP=y
+CONFIG_DEBUG_BLK_CGROUP=y
CONFIG_CGROUP_SCHED=y
+CONFIG_CFS_BANDWIDTH=y
CONFIG_FAIR_GROUP_SCHED=y
CONFIG_CFS_BANDWIDTH=y
# CONFIG_RT_GROUP_SCHED is not set
-# CONFIG_CGROUP_PIDS is not set
-# CONFIG_CGROUP_RDMA is not set
+CONFIG_CGROUP_PIDS=y
+CONFIG_CGROUP_RDMA=y
CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_HUGETLB=y
CONFIG_CPUSETS=y
CONFIG_PROC_PID_CPUSET=y
-# CONFIG_CGROUP_DEVICE is not set
+CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
-# CONFIG_CGROUP_PERF is not set
+CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_BPF=y
# CONFIG_CGROUP_DEBUG is not set
CONFIG_SOCK_CGROUP_DATA=y
-# CONFIG_CHECKPOINT_RESTORE is not set
+CONFIG_CHECKPOINT_RESTORE=y
CONFIG_NAMESPACES=y
CONFIG_UTS_NS=y
-# CONFIG_USER_NS is not set
+CONFIG_USER_NS=y
CONFIG_PID_NS=y
CONFIG_NET_NS=y
# CONFIG_SCHED_AUTOGROUP is not set
@@ -209,7 +213,7 @@ CONFIG_BPF_JIT_ALWAYS_ON=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_ADVISE_SYSCALLS=y
-# CONFIG_USERFAULTFD is not set
+CONFIG_USERFAULTFD=y
CONFIG_MEMBARRIER=y
CONFIG_EMBEDDED=y
CONFIG_HAVE_PERF_EVENTS=y
@@ -268,6 +272,7 @@ CONFIG_CC_STACKPROTECTOR=y
# CONFIG_CC_STACKPROTECTOR_NONE is not set
# CONFIG_CC_STACKPROTECTOR_REGULAR is not set
CONFIG_CC_STACKPROTECTOR_STRONG=y
+CONFIG_BLK_DEV_THROTTLING=y
CONFIG_THIN_ARCHIVES=y
# CONFIG_LTO is not set
CONFIG_ARCH_SUPPORTS_LTO_CLANG=y
@@ -462,9 +467,9 @@ CONFIG_QCOM_FALKOR_ERRATUM_E1041=y
CONFIG_ARM64_4K_PAGES=y
# CONFIG_ARM64_16K_PAGES is not set
# CONFIG_ARM64_64K_PAGES is not set
-CONFIG_ARM64_VA_BITS_39=y
-# CONFIG_ARM64_VA_BITS_48 is not set
-CONFIG_ARM64_VA_BITS=39
+# CONFIG_ARM64_VA_BITS_39 is not set
+CONFIG_ARM64_VA_BITS_48=y
+CONFIG_ARM64_VA_BITS=48
# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_SCHED_MC=y
# CONFIG_SCHED_SMT is not set
@@ -597,7 +602,7 @@ CONFIG_ELFCORE=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_BINFMT_SCRIPT=y
# CONFIG_HAVE_AOUT is not set
-# CONFIG_BINFMT_MISC is not set
+CONFIG_BINFMT_MISC=y
CONFIG_COREDUMP=y
CONFIG_COMPAT=y
@@ -698,10 +703,10 @@ CONFIG_NET_EGRESS=y
# Networking options
#
CONFIG_PACKET=y
-# CONFIG_PACKET_DIAG is not set
+CONFIG_PACKET_DIAG=y
CONFIG_UNIX=y
CONFIG_UNIX_SCM=y
-# CONFIG_UNIX_DIAG is not set
+CONFIG_UNIX_DIAG=y
# CONFIG_TLS is not set
CONFIG_XFRM=y
CONFIG_XFRM_ALGO=y
@@ -807,6 +812,7 @@ CONFIG_NETWORK_SECMARK=y
# CONFIG_NET_PTP_CLASSIFY is not set
# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
CONFIG_NETFILTER=y
+CONFIG_BRIDGE_NETFILTER=y
CONFIG_NETFILTER_ADVANCED=y
#
@@ -899,9 +905,9 @@ CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
#
# Xtables matches
#
-# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=y
CONFIG_NETFILTER_XT_MATCH_BPF=y
-# CONFIG_NETFILTER_XT_MATCH_CGROUP is not set
+CONFIG_NETFILTER_XT_MATCH_CGROUP=y
# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set
CONFIG_NETFILTER_XT_MATCH_COMMENT=y
CONFIG_NETFILTER_XT_MATCH_CONNBYTES=y
@@ -920,6 +926,7 @@ CONFIG_NETFILTER_XT_MATCH_HELPER=y
CONFIG_NETFILTER_XT_MATCH_HL=y
# CONFIG_NETFILTER_XT_MATCH_IPCOMP is not set
CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
+CONFIG_NETFILTER_XT_MATCH_IPVS=y
CONFIG_NETFILTER_XT_MATCH_L2TP=y
CONFIG_NETFILTER_XT_MATCH_LENGTH=y
CONFIG_NETFILTER_XT_MATCH_LIMIT=y
@@ -946,7 +953,11 @@ CONFIG_NETFILTER_XT_MATCH_STRING=y
CONFIG_NETFILTER_XT_MATCH_TIME=y
CONFIG_NETFILTER_XT_MATCH_U32=y
# CONFIG_IP_SET is not set
-# CONFIG_IP_VS is not set
+CONFIG_IP_VS=y
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_RR=y
+CONFIG_IP_VS_NFCT=y
#
# IP: Netfilter Configuration
@@ -1078,7 +1089,7 @@ CONFIG_NET_CLS_U32=y
# CONFIG_NET_CLS_RSVP is not set
# CONFIG_NET_CLS_RSVP6 is not set
# CONFIG_NET_CLS_FLOW is not set
-# CONFIG_NET_CLS_CGROUP is not set
+CONFIG_NET_CLS_CGROUP=y
CONFIG_NET_CLS_BPF=y
# CONFIG_NET_CLS_FLOWER is not set
# CONFIG_NET_CLS_MATCHALL is not set
@@ -1114,7 +1125,7 @@ CONFIG_NET_SCH_FIFO=y
# CONFIG_BATMAN_ADV is not set
# CONFIG_OPENVSWITCH is not set
# CONFIG_VSOCKETS is not set
-# CONFIG_NETLINK_DIAG is not set
+CONFIG_NETLINK_DIAG=y
# CONFIG_MPLS is not set
# CONFIG_NET_NSH is not set
# CONFIG_HSR is not set
@@ -1125,7 +1136,7 @@ CONFIG_KNOX_NCM=y
CONFIG_RPS=y
CONFIG_RFS_ACCEL=y
CONFIG_XPS=y
-# CONFIG_CGROUP_NET_PRIO is not set
+CONFIG_CGROUP_NET_PRIO=y
# CONFIG_CGROUP_NET_CLASSID is not set
CONFIG_NET_RX_BUSY_POLL=y
CONFIG_BQL=y
@@ -1539,7 +1550,7 @@ CONFIG_DM_BUFIO=y
# CONFIG_DM_CRYPT is not set
CONFIG_DM_DEFAULT_KEY=y
CONFIG_DM_SNAPSHOT=y
-# CONFIG_DM_THIN_PROVISIONING is not set
+CONFIG_DM_THIN_PROVISIONING=y
# CONFIG_DM_CACHE is not set
# CONFIG_DM_ERA is not set
# CONFIG_DM_MIRROR is not set
@@ -1566,8 +1577,8 @@ CONFIG_DUMMY=y
# CONFIG_EQUALIZER is not set
# CONFIG_IFB is not set
# CONFIG_NET_TEAM is not set
-# CONFIG_MACVLAN is not set
-# CONFIG_VXLAN is not set
+CONFIG_MACVLAN=y
+CONFIG_VXLAN=y
# CONFIG_GENEVE is not set
# CONFIG_GTP is not set
# CONFIG_MACSEC is not set
@@ -5165,7 +5176,8 @@ CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
CONFIG_INOTIFY_USER=y
-# CONFIG_FANOTIFY is not set
+CONFIG_FANOTIFY=y
+CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
CONFIG_QUOTA=y
CONFIG_QUOTA_NETLINK_INTERFACE=y
CONFIG_PRINT_QUOTA_WARNING=y
@@ -5176,11 +5188,11 @@ CONFIG_QFMT_V2=y
CONFIG_QUOTACTL=y
# CONFIG_AUTOFS4_FS is not set
CONFIG_FUSE_FS=y
-# CONFIG_CUSE is not set
+CONFIG_CUSE=y
CONFIG_FUSE_SUPPORT_STLOG=y
CONFIG_OVERLAY_FS=y
-# CONFIG_OVERLAY_FS_REDIRECT_DIR is not set
-# CONFIG_OVERLAY_FS_INDEX is not set
+CONFIG_OVERLAY_FS_REDIRECT_DIR=y
+CONFIG_OVERLAY_FS_INDEX=y
CONFIG_INCREMENTAL_FS=y
#
@@ -5246,7 +5258,7 @@ CONFIG_SYSFS=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_TMPFS_XATTR=y
-# CONFIG_HUGETLBFS is not set
+CONFIG_HUGETLBFS=y
# CONFIG_HUGETLB_PAGE is not set
CONFIG_ARCH_HAS_GIGANTIC_PAGE=y
CONFIG_CONFIGFS_FS=y
diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
index cdcdd9d0b388..4c15285d233b 100644
--- a/kernel/cgroup/cpuset.c
+++ b/kernel/cgroup/cpuset.c
@@ -1944,6 +1944,103 @@ static struct cftype files[] = {
.write_u64 = cpuset_write_u64,
.private = FILE_MEMORY_PRESSURE_ENABLED,
},
+ {
+ .name = "cpuset.cpus",
+ .seq_show = cpuset_common_seq_show,
+ .write = cpuset_write_resmask,
+ .max_write_len = (100U + 6 * NR_CPUS),
+ .private = FILE_CPULIST,
+ },
+
+ {
+ .name = "cpuset.mems",
+ .seq_show = cpuset_common_seq_show,
+ .write = cpuset_write_resmask,
+ .max_write_len = (100U + 6 * MAX_NUMNODES),
+ .private = FILE_MEMLIST,
+ },
+
+ {
+ .name = "cpuset.effective_cpus",
+ .seq_show = cpuset_common_seq_show,
+ .private = FILE_EFFECTIVE_CPULIST,
+ },
+
+ {
+ .name = "cpuset.effective_mems",
+ .seq_show = cpuset_common_seq_show,
+ .private = FILE_EFFECTIVE_MEMLIST,
+ },
+
+ {
+ .name = "cpuset.cpu_exclusive",
+ .read_u64 = cpuset_read_u64,
+ .write_u64 = cpuset_write_u64,
+ .private = FILE_CPU_EXCLUSIVE,
+ },
+
+ {
+ .name = "cpuset.mem_exclusive",
+ .read_u64 = cpuset_read_u64,
+ .write_u64 = cpuset_write_u64,
+ .private = FILE_MEM_EXCLUSIVE,
+ },
+
+ {
+ .name = "cpuset.mem_hardwall",
+ .read_u64 = cpuset_read_u64,
+ .write_u64 = cpuset_write_u64,
+ .private = FILE_MEM_HARDWALL,
+ },
+
+ {
+ .name = "cpuset.sched_load_balance",
+ .read_u64 = cpuset_read_u64,
+ .write_u64 = cpuset_write_u64,
+ .private = FILE_SCHED_LOAD_BALANCE,
+ },
+
+ {
+ .name = "cpuset.sched_relax_domain_level",
+ .read_s64 = cpuset_read_s64,
+ .write_s64 = cpuset_write_s64,
+ .private = FILE_SCHED_RELAX_DOMAIN_LEVEL,
+ },
+
+ {
+ .name = "cpuset.memory_migrate",
+ .read_u64 = cpuset_read_u64,
+ .write_u64 = cpuset_write_u64,
+ .private = FILE_MEMORY_MIGRATE,
+ },
+
+ {
+ .name = "cpuset.memory_pressure",
+ .read_u64 = cpuset_read_u64,
+ .private = FILE_MEMORY_PRESSURE,
+ },
+
+ {
+ .name = "cpuset.memory_spread_page",
+ .read_u64 = cpuset_read_u64,
+ .write_u64 = cpuset_write_u64,
+ .private = FILE_SPREAD_PAGE,
+ },
+
+ {
+ .name = "cpuset.memory_spread_slab",
+ .read_u64 = cpuset_read_u64,
+ .write_u64 = cpuset_write_u64,
+ .private = FILE_SPREAD_SLAB,
+ },
+
+ {
+ .name = "cpuset.memory_pressure_enabled",
+ .flags = CFTYPE_ONLY_ON_ROOT,
+ .read_u64 = cpuset_read_u64,
+ .write_u64 = cpuset_write_u64,
+ .private = FILE_MEMORY_PRESSURE_ENABLED,
+ },
{ } /* terminate */
};
为了防止内核panic,也可能需要合并这个diff(不过我并没有找到这个文件和这个函数,所以我就没改,这个是在网上抄的)
xt_qtaguid.diff
--- net/netfilter/xt_qtaguid.c 2023-07-02 00:07:55.000000000 +0800
+++ net/netfilter/xt_qtaguid.c 2023-07-02 05:20:40.000000000 +0800
@@ -738,7 +738,7 @@ static int iface_stat_fmt_proc_show(stru
{
struct proc_iface_stat_fmt_info *p = m->private;
struct iface_stat *iface_entry;
- struct rtnl_link_stats64 dev_stats, *stats;
+ struct rtnl_link_stats64 *stats;
struct rtnl_link_stats64 no_dev_stats = {0};
@@ -747,12 +747,7 @@ static int iface_stat_fmt_proc_show(stru
iface_entry = list_entry(v, struct iface_stat, list);
- if (iface_entry->active) {
- stats = dev_get_stats(iface_entry->net_dev,
- &dev_stats);
- } else {
- stats = &no_dev_stats;
- }
+ stats = &no_dev_stats;
/*
* If the meaning of the data changes, then update the fmtX
* string.
接下来处理系统源码,这里处理系统源码主要是因为你在内核中打开了SYSV_IPC
等开关,导致Android的内核检查过不去,不仅编译会报错,用一些奇技淫巧编译出的东西刷到设备上也会显示您的设备内部出现了问题,请联系您的设备制造商了解详情
弹窗,虽然不影响正常使用,但是很影响心情,所以需要把检查的代码做一下修改。这里需要合并两个diff,分别属于不同的git仓库(虽然都在源码文件夹下但是属于不同的git仓库。真有你的啊repo,这就是我们的repo啊,你们有这样的repo吗?真是又re又po啊)
在frameworks/base下合并:
base.diff
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index ad9ac201e22b..1eaea3d6c6f3 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -6235,7 +6235,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
} catch (RemoteException e) {
}
- if (!isBuildConsistent) {
+ if (false && !isBuildConsistent) {
Slog.e(TAG, "Build fingerprint is not consistent, warning user");
mUiHandler.post(() -> {
if (mShowDialogs) {
在system/libvintf下合并:
check_vintf.diff
diff --git a/check_vintf.cpp b/check_vintf.cpp
index 2f513ed..7f6b507 100644
--- a/check_vintf.cpp
+++ b/check_vintf.cpp
@@ -652,7 +652,8 @@ int main(int argc, char** argv) {
if (compat.error().code() == 0) {
LOG(ERROR) << "ERROR: files are incompatible: " << compat.error();
std::cout << "INCOMPATIBLE" << std::endl;
- return EX_DATAERR;
+ //return EX_DATAERR;
+ return EX_OK;
}
LOG(ERROR) << "ERROR: " << strerror(compat.error().code()) << ": " << compat.error();
return EX_SOFTWARE;
合并结束后,重新整编,处理好报错,刷入设备即可。
lxc的安装
在处理好内核和源码之后,下一步要做的就是安装lxc了。
在Termux诞生之后,安装lxc或docker就变得很简单了,你只需要安装一个termux,添加root-repo后,即可通过
apt install lxc
apt install docker
命令安装lxc和docker了。如果想要自己编译,也可以fork termux官方的repo仓库,简单修改一下配置即可在Github Actions中跑编译过程了。不得不说,Termux的诞生真的是Android玩机领域最伟大的成就了(仅次于Lineage OS的诞生)。
需要注意的是,在安装docker的时候会弹出一条提示需要mount cgroup才可以正常使用,其实lxc也有这个要求,不过termux中lxc的维护者给我们提供了一个脚本:lxc-setup-cgroups
来完成这个要求,不过对于使用了systemd的guest来说,这个脚本中挂载的cgroup并不全,需要增加下面一行:
sudo mkdir -p /sys/fs/cgroup/systemd && sudo mount -t cgroup cgroup -o none,name=systemd /sys/fs/cgroup/systemd
不然lxc启动使用systemd的guest时会报错,非systemd的我没测,不过应该是没啥问题。
在GUI方面,我选择了目前比较火热的termux-x11
,我其实尝试过很多的解决方案,VNC
,xsdl
,不过最令我满意的还是termux-x11
,无论是速度还是易用性都无法挑剔,不过如果能出一个一键启动不需要输命令的就更好了(我挖坑了奥,看我能不能填上吧)
为了配置x11和网络,需要运行如下的代码:
sed -i 's/lxc\.net\.0\.type = empty/lxc.net.0.type = none/g' $PREFIX/etc/lxc/default.conf
echo 'lxc.mount.entry = tmpfs tmp tmpfs defaults' >> $PREFIX/etc/lxc/default.conf
echo 'lxc.mount.entry = /data/data/com.termux/files/usr/tmp/.X11-unix tmp/.X11-unix none ro,bind,create=dir 0 0' >> $PREFIX/etc/lxc/default.conf
在创建容器之前运行一次即可,在以后创建容器时lxc会自动应用上面的配置。
在安装好termux-x11(请根据官方仓库中的文档安装)后,需要先运行起来才可以开启lxc容器。新建一个session,输入:
termux-x11 :0
即可运行一个termux-x11实例了。
在安装了lxc并运行lxc-checkconfig
确认内核无误后(没有红色missing即可),即可开始创建容器了:
lxc-create -t download -n my-container -- --server mirrors.tuna.tsinghua.edu.cn/lxc-images --no-validate
# 依次填入发行版 版本号 架构
# 然后启动
lxc-start -n my-container -d -F
其中my-container
是容器名称,可以自行确定。
此外,有可能出现不知道root密码的情况,这种时候需要另起一个session,进入tsu,输入
lxc-attach -n my-container /usr/bin/passwd
即可修改root密码。
sudo的问题
在某些设备上(我这台就是)进入lxc使用sudo会提示sudo: 有效用户 ID 不是 0,/usr/bin/sudo 位于一个设置了“nosuid”选项的文件系统或没有 root 权限的 NFS 文件系统中吗?
或者sudo: effective uid is not 0, is sudo installed setuid root?
或者类似的提示,这时候你需要将你的设备中的fstab修改一下,具体的修改其实就是把/data的挂载参数中的nosuid去掉,对于我的设备来说就是这样:
nosuid.diff
diff --git a/configs/init/fstab.exynos9611 b/configs/init/fstab.exynos9611
index 71f1db5..e1657a6 100644
--- a/configs/init/fstab.exynos9611
+++ b/configs/init/fstab.exynos9611
@@ -15,7 +15,7 @@ odm /odm
/dev/block/platform/13520000.ufs/by-name/recovery /recovery emmc defaults recoveryonly
/dev/block/platform/13520000.ufs/by-name/vbmeta /vbmeta emmc defaults first_stage_mount
/dev/block/platform/13520000.ufs/by-name/cache /cache ext4 noatime,nosuid,nodev,noauto_da_alloc,discard,journal_checksum,data=ordered,errors=panic wait,check
-/dev/block/platform/13520000.ufs/by-name/userdata /data f2fs noatime,nosuid,nodev,discard,reserve_root=32768,resgid=1065,fsync_mode=nobarrier,inlinecrypt latemount,wait,check,quota,formattable,checkpoint=fs,fileencryption=aes-256-xts:aes-256-cts:v2+inlinecrypt_optimized,metadata_encryption=aes-256-xts,keydirectory=/metadata/vold/metadata_encryption,fscompress,readahead_size_kb=128
+/dev/block/platform/13520000.ufs/by-name/userdata /data f2fs noatime,nodev,discard,reserve_root=32768,resgid=1065,fsync_mode=nobarrier,inlinecrypt latemount,wait,check,quota,formattable,checkpoint=fs,fileencryption=aes-256-xts:aes-256-cts:v2+inlinecrypt_optimized,metadata_encryption=aes-256-xts,keydirectory=/metadata/vold/metadata_encryption,fscompress,readahead_size_kb=128
/dev/block/platform/13520000.ufs/by-name/efs /mnt/vendor/efs ext4 noatime,nosuid,nodev,noauto_da_alloc,discard,journal_checksum,data=ordered,errors=panic wait,check
/dev/block/platform/13520000.ufs/by-name/cpefs /mnt/vendor/cpefs ext4 noatime,nosuid,nodev,noauto_da_alloc,discard,journal_checksum,data=ordered,errors=panic wait,check,nofail
/dev/block/platform/13520000.ufs/by-name/misc /misc emmc defaults defaults
结语
其实到这里就已经把lxc跑通了,剩下的就是安装一下桌面环境之类的小问题了,在启动桌面环境的时候只需要注意前面要加DISPLAY变量即可,例如:
DISPLAY=:0 gnome-session
刚才提到了我挖了个坑,这其实是我觉得现在的启动流程实在是有点复杂,而且并没有用上dm,需要在命令行下输入命令才可以打开session。为了方便我自己,我想要写一系列的小东西用来自动化这个过程并且使用一些奇技淫巧让dm正常运行,以便可以在gui下登录。看我的时间吧,有时间再说。