【持续更新】Ubuntu && 安卓内核小技巧

Ubuntu && 安卓内核小技巧

1. Ubuntu 终端命令

  1. 全局搜索:grep xxx -niR
  2. 以 root 权限打开根目录文件夹:sudo nautilus
  3. 去除文件锁:sudo chmod 777 [filename]
  4. 去除文件夹内所有文件锁:sudo chmod -R 777 .
  5. 清空垃圾箱:sudo rm -rf ~/.local/share/Trash/*

2. 防止编译时因为未使用的变量或函数而引发错误警告

以 pixel 3xl 的内核版本 android-msm-crosshatch-4.9-android12 为例
./private/msm-google/Makefile 中,找到以下代码:

KBUILD_CFLAGS   := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
		   -fno-strict-aliasing -fno-common -fshort-wchar \
		   -Werror-implicit-function-declaration \
		   -Wno-format-security \
		   -std=gnu89

我们在 -Wno-format-security \ 下方加入两条语句:

		   -Wno-unused-variable \
		   -Wno-unused-function \

再次编译就不会报错了

3. 查询进程 id 方法

a. shell 方法

  1. adb shell dumpsys activity top|grep “ACTIVITY”

    查询当前所有活动的进程的 tgid

    root@ubuntu:~# adb shell dumpsys activity top|grep "ACTIVITY"
    	ACTIVITY com.ss.android.ugc.aweme/.splash.SplashActivity e05d114 pid=21855
    	ACTIVITY com.android.launcher3/.uioverrides.QuickstepLauncher 9baf895 pid=2708
    	ACTIVITY com.taobao.taobao/com.taobao.tao.TBMainActivity f4df805 pid=13263
    
  2. adb shell ps -eo pid,args,psr|grep “包名”

    查询指定进程的 pid,包含了当前进程所在的 tgid 中的所有 pid

    root@ubuntu:~# adb shell ps -eo pid,args,psr|grep "android.ugc.aweme"
    21855 com.ss.android.ugc.aweme      7
    22967 com.ss.android.ugc.aweme:push 7
    
  3. adb shell pgrep -f “包名”

    查询指定进程的 pid,该方法只输出 pid 不输出其他信息,无法分辨哪一个是主线程的 id

    root@ubuntu:~# adb shell pgrep -f android.ugc.aweme
    21855
    22967
    

b. 内核查询进程id方法

  1. task_pid_nr(current):查询当前任务的 pid
  2. task_tgid_nr(current):查询当前任务的 tgid

4. 终端打印信息:printk()

在内核中加入语句:printk(KERN_EMERG "print what you want in cpu=%d", cpu);

编译过后进入 shell
输入 dmesg -w 可以实时打印你想要的信息
输入 dmesg | grep [关键词] 可以打印已有的你想要的含有关键词的信息
输入 dmesg -w | grep [关键词] 可以实时打印你想要的含有关键词的信息

注意:

  1. 在定义变量代码前边出现printk函数,编译时会出现这个错误:
    error: ISO C90 forbids mixed declarations and code [-Werror=declaration-after-statement]

    同时,我们可以利用这个错误,来试探该部分是否被编译。

  2. 如果频率过高,printk 打印出来的信息可能会错位,如果需要按照时间戳打印最好使用 ftrace 等方式

5. 日志打印信息

a. ftrace(简单介绍)

假如我想要在 /kernel/msm-5.4/kernel/sched/core.c 中加入一个 trace 事件,我可以先看是否有自带的存放 trace point 的头文件,如:#include <trace/events/sched.h>

那么,我可以在 include/trace/events/sched.h 中放入以下代码(可以说是模板):

TRACE_EVENT(data_example,

	TP_PROTO(int cpu, struct task_struct *t, bool flag),

	TP_ARGS(cpu, t, flag),

	TP_STRUCT__entry(
		__array(	char,			comm,	TASK_COMM_LEN		)
		__field(	int,			cpu							)
		__field(	int,			freq						)
		__field(	bool,			flag						)
	),

	TP_fast_assign(
		memcpy(__entry->comm, t->comm, TASK_COMM_LEN);
		__entry->cpu	= cpu;
		__entry->freq	= cpufreq_quick_get(cpu);
		__entry->flag	= flag;
	),

	TP_printk("cpu=%d freq=%d switch=%s task_comm=%s", 
	__entry->cpu, __entry->freq, __entry->flag ? "BEGIN" : "END", __entry->comm)
);

如果编译报错,可能需要加上以下定义代码:

DEFINE_EVENT(data_example, data_example,
	     TP_PROTO(int cpu, struct task_struct *t, bool flag),
	     TP_ARGS(cpu, t, flag));

在编译完成刷机结束后,就可以通过以下 shell 命令打开 trace 事件并开始 trace:

echo 0 > /sys/kernel/tracing/tracing_on
// 如果 trace 文件中发现数据不全,可以尝试通过以下 shell 指令解决
echo 96000 > /sys/kernel/tracing/buffer_size_kb
echo 1 > /sys/kernel/tracing/events/sched/data_example/enable
echo 1 > /sys/kernel/tracing/tracing_on
/* 执行操作 */
echo 0 > /sys/kernel/tracing/tracing_on

将 trace 结果文件保存至本地:

// 根据关键词从 trace 结果文件中提取信息
adb shell "cat /sys/kernel/tracing/trace | grep data_example" > data_trace/data_example.txt
// 将整个 trace 结果文件取出
adb pull /sys/kernel/tracing/trace D:\data_trace\trace.txt

6. 定频

进入 adb shell 后将某个簇上的最大频率和最小频率都设定为同一个频率,即可实现定频:
echo {想要的频率} > /sys/devices/system/cpu/cpufreq/policy{想要的簇}/scaling_min_freq
echo {想要的频率} > /sys/devices/system/cpu/cpufreq/policy{想要的簇}/scaling_max_freq
值得注意的是,因为某些策略会导致频率可能定不住。

7. 任务绑核

参考文章:Linux下的绑核命令—taskset

掩码形式绑核

将掩码转换为二进制形式,从最低位到最高位代表物理CPU的#0、#1、……、#n号核。某位的值为0表示不绑该核,1表示绑。比如:0x00000001的二进制为0000…0001,只有第0号核的位置是1,所以表示只绑0号核;0x00000003的二进制为0000…0011,第0和1号核的位置是1,所以表示绑CPU的0号和1号核;再比如0xFFFFFFFF的二进制为1111…1111,所有32个核的位置都为1,所以表示绑CPU的0~31核。

需要注意的是,并非掩码中给出的CPU核就一定会存在,比如0x00000400理论上代表CPU的第10号核,但是该核在真正的计算机上面并不一定是存在的。而且,如果我们试图将物理上并不存的核绑定给某个进程时,会返回错误。掩码形式的绑核命令为:

adb shell taskset -p {16进制的CPU号} {任务pid}

列表形式

列表形式指直接指定要绑的CPU核的列表,列表中可以有一个或多个核。具体语法如下:

adb shell taskset -cp {10进制的CPU号,可以以逗号分隔} {任务pid}

其中cpu-list是数字化的cpu列表,从0开始。多个不连续的cpu可用逗号连接,连续的可用短现连接,比如0,2,5-11等。

比如taskset -cp 0,2,5-11 9865命令表示将进程9865绑定到#0、#2、#5~#11号核上面。

最后要说的是:只要taskset成功返回了,那就表示绑核一定成功了,即该进程已被绑到指定的核上面,而且taskset命令会显示原来的绑核(原来的可能是系统默认分配的核)情况,以及新的绑核情况。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值