Linux内核设计与实现总结(8) —— I/O子系统

I/O子系统

本人觉得I/O子系统是Linux内核中最难的东西,因为它需要兼容横跨物理介质、文件系统、空间位置(网络),为上层提供统一接口,还需要保持高性能,这简直amazing。

I/O子系统的架构图如上图所示。

这里将Linux I/O子系统分为VFS(虚拟文件系统)、块I/O、高速缓存这三个部分总结。

Read more

Linux内核设计与实现总结(3) —— 进程管理与进程调度

进程与线程

Linux内核是不区分线程与进程的,线程只是一种特殊的进程,被视为与其他进程共享地址空间的进程。与windows这种在内核专门提供线程支持的操作系统不一样。

task_struct与thread_info

图片来自biscuitos.github.io

task_struct(进程描述符)描述了一个进程的所有信息,是一个体系无关的结构,位于include/linux/sched.h。它包含进程打开的文件、挂起的信号、进程的状态、进程的pid等。保存在tasks双向循环链表中(见上一节的链表结构体总结),因此可以从一个进程结构体出发,索引到任何其他进程结构体。目前内核中,进程描述符是用slab分配器动态生成的,task_struct有一个void *stack成员变量指向进程的内核栈。

thread_info是体系相关的,位于arch/xxx/include/asm/thread_info.h,它存放了线程上下文,包括是否可以抢占、当前进程是属于哪一种规范的可执行程序等。

早期内核配置中,在X86体系并且CONFIG_THREAD_INFO_IN_TASK没有被时,进程的thread_info存放在进程的内核栈。如果是向下增长的栈,则thread_info在栈顶低地址;向上增长的栈,thread_info还是在低地址,只不过在栈底了。因此,可以通过内核栈的地址快速获得thread_info的地址。

在thread_info中有一个struct task_struct *task变量指向task_struct。后来内核把X86的thread_info结构体中的这个task指针给去掉了(Move thread_info into task_struct),并且将thread_info放到了task_struct中。这个task指针,是为了寄存器在不够多的体系上,可以通过内核栈地址加偏移,找到thread_info,然后快速找到task_struct的。但是X86一直使用的是per_cpu的变量来保存正在使用cpu的进程的进程描述符:

1
DECLARE_PER_CPU(struct task_struct *, current_task);

所以thread_info中的task变量是可有可无的。

在进程调度时,会更新这个变量:

1
this_cpu_write(current_task, next_p);
Read more

Linux内核设计与实现总结(2) —— 内核数据结构

内核数据结构

Linux内核中实现了一些常见的数据结构,而且内核要求代码越高效越好,所以这些数据结构的实现极为优雅!因此,千万不要自己实现山寨的数据结构。

内核的数据结构包括:

  1. 链表(双向循环)
  2. 队列
  3. IDR & IDA
  4. 红黑树

链表

链表头文件

位于include/linux/link.h

Read more

Linux内核设计与实现总结(1) —— qemu内核调试环境搭建(macOS)

宿主机系统

  1. macOS 12.4 (x86)

安装qemu

qemu相比于vmware,简单、轻便,可以直接指定linux内核,再指定一个文件系统,即可调试。硬盘、网络设备可以后加。

首先我尝试了utmapp/UTM,这是个适用于iOS/macOS的虚拟机,基于qemu。但是在指定内核启动镜像bzImage和initramfs后,遇到了问题,一直报错:

1
The bootindex 0 has already been used

搞了一会没搞出来,索性不用UTM了,直接上qemu。

使用homebrew可以直接安装qemu。

1
➜  ~ brew install qemu

目前安装的是7.0.0_2。

安装完成之后验证一下:

1
2
3
4
5
6
7
➜  ~ qemu-system-x86_64 --help
QEMU emulator version 7.0.0
Copyright (c) 2003-2022 Fabrice Bellard and the QEMU Project developers
usage: qemu-system-x86_64 [options] [disk_image]

'disk_image' is a raw hard disk image for IDE hard disk 0
....
Read more

折腾:无线宝鲁班openwrt 21.02.1

免责声明

  1. 仅用于测试与学习研究,作者没有对该设备进行任何形式的“破解”,所有信息都是通过正常的方式获取。
  2. 如果任何单位或个人认为本文内容可能涉嫌侵犯其权利,则应及时联系作者并要求删除相关内容。
  3. 作者对本文带来的潜在问题概不负责,包括但不限于由任何错误导致的任何损失或损害。

前言

前几天在京东上买了个京东云无线宝鲁班,硬件配置如下:

1
2
3
4
5
CPU:MT7621A
内存:南亚512MB
闪存:XM25QH128C 128Mit/16MB
无线:MT7975DN + MT7905DAN
网口:全千兆LLLW

本来天天放那边跑分换京豆的,但是这官方固件实在有点用不下去,所以给它搞个适配个openwrt吧。

Read more

Kernel Compile Guide(clang)

Guide

  1. Add the Clang commits to your kernel source
    https://android.googlesource.com/kernel/common/+log/f0907aa15ed9f9c7541bb244ed3f52c376ced19c
  2. Download/build a compatible Clang toolchain
  3. Download/build a copy of binutils
  4. Compile the kernel (for arm64, x86_64 is similar - example using AOSP’s toolchains):
1
2
3
4
5
6
7
8
9
10
11
export PATH=/home/ubuntu/gcc/bin:$PATH
export PATH=/home/ubuntu/clang/bin:$PATH
export CROSS_COMPILE=aarch64-linux-android-
export CLANG_TRIPLE=aarch64-linux-gnu-
export ARCH=arm64
export SUBARCH=arm64

make clean
make mrproper
make O=out lcblues-perf_defconfig
make -j$(nproc --all) O=out CC=clang CONFIG_DEBUG_SECTION_MISMATCH=y
1
make -j$(nproc --all) O=out

CC=clang CLANG_TRIPLE=aarch64-linux-gnu-

op5-perf_defconfig or msmcortex-perf_defconfig
After compiling, you can verify the toolchain used by opening out/include/generated/compile.h and looking at the LINUX_COMPILER option.

A couple of notes:

CLANG_TRIPLE is only needed when using AOSP’s version of Clang
export CC=clang does not work. You need to pass CC=clang to make like above.

关于git cherry-pick

首先fork一加官方kernel,然后clone自己仓

1
git clone 

清除无用的分支,再add一个一加官方的remote

1
2
git branch -r -d <branch>
git push origin <branch>
1
2
git remote add op https://github.com/OnePlusOSS/android_kernel_oneplus_msm8998
git fetch op HEAD:oneplus/QC8998_P_9.0

把它这个拿下来
切换到自己的QC8998_P_9.0分支,并merge一下

1
2
git checkout oneplus/QC8998_P_9.0
git merge op/oneplus/QC8998_P_9.0

或者自己cherry-pick

1
git cherry-pick commitid^..commitid

Problem

  1. WLAN驱动qca_cld3_wlan.ko的问题

一加官方内核repo里面是不包含qcacld3.0的源码的。它在开机的时候加载insmod /vedor/lib/module/qca_cl3_wlan.ko,见 /vendor/etc/init/hw/init.target.rc

但模块存在一个check_version的校验的问题,你如果不是从源码编译而来的,基本是过不去的,因此在启动的时候,驱动没加载,开机就没WiFi。

那么为什么Custom Rom没有这个问题?Custom Rom的内核是由CAF基线+一加的一些修改而成的,包含qcacld3源码,并且配置成includes到内核里。

那为什么第三方基于一加内核源码魔改的内核没有这个问题呢?特意看了commit,它魔改了/kernel/module.c,check_version遇到wlan直接return 1了。

现在我处于菜鸟阶段,因此我cherry-pick了这个commit…嘻嘻

  1. Clang LTO

还没开始,但可以肯定的是必遇到问题。

  1. 手势用不了

fixed

  1. Clang编译 CPU 总是Max Freq

fixed

  1. ZRAM LZ4

added

  1. EAS

added

  1. Dynamic SchedTune Boost

added

  1. wakelock

todo

  1. more tcp congestion control algorithm

todo

OrangeFox Recovery编译记录

基于TWRP修改的,界面挺帅

问题:

  1. /sbin/foxstart.sh找不到
  2. 系统开机卡第一界面
  3. App Manager用不了
  4. 中文显示为口口

解决

Read more