msm8998 (Snapdragon 835) 降压 undervolt

理论

如何在不编译内核的情况下,修改现有boot的dts呢

boot由几部分组成

  1. kernel
  2. dtb

利用device-tree-compiler对dtb反编译即可,但Android的dtb,包含不同dtb block,dtc只会反编译在头部的dtb,如何一次性全部反编译?

本来想用hexdump或者xxd康康16进制然后dd分割,但实在太复杂,shell不是很会写,感觉掌控不了它,因此自己用c写了个小东西,上代码,具体怎么分割的,可以康康dtb文件解析,head totalsize等等。

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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include <getopt.h>
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>

typedef struct dtb_info {
uint32_t total_size;
uint32_t addr_start;
uint32_t addr_stop;
char *new_file;
} dtb;

static void die(char *message) {
fprintf(stderr, message);
exit(EXIT_FAILURE);
}

static void usage(char *argv0) {
printf("Example: \n\t%s -i kernel_dtb\n", argv0);
exit(EXIT_FAILURE);
}

static void check_arg(int argc, char *argv[], char *dtb_file) {
char optstring[] = "i:";
int c, index = 0;
int input_exist = 0;
struct option options[] = {
{"input", 1, NULL, 'i'},
{0, 0, 0, 0},
};
while ((c = getopt_long(argc, argv, optstring, options, &index)) != -1) {
switch (c) {
case 'i':
strcpy(dtb_file, optarg);
input_exist = 1;
break;
default:
usage(argv[0]);
break;
}
}
if(input_exist!=1){
usage(argv[0]);
}
}

static void *memcpy_(void *dest, void *src, size_t size) {
uint8_t *d = (uint8_t *)dest;
uint8_t *s = (uint8_t *)src;
int i = 0;
while (size-- > 0) {
d[size] = s[i];
i++;
}
return dest;
}

int main(int argc, char *argv[]) {
char *file_ = malloc(sizeof(char) * 100);
char *filename = malloc(sizeof(char) * 100);
check_arg(argc,argv,file_);

struct stat filebuff;
stat(file_, &filebuff);
long filesize = filebuff.st_size;

uint8_t buff[4]; // read 4 hex 1 time
uint8_t head[4] = {0xD0, 0x0D, 0xFE, 0xED};
uint8_t buff_c;
FILE *fp = fopen(file_, "rb");
if (fp == NULL) {
fclose(fp);
die("open dtb file failed\n");
}

fgets(buff, 5, fp); // compare with head
int ret = memcmp(&buff, &head, sizeof(buff));
if (ret != 0) {
fclose(fp);
die("not valid dtb file\n");
}

dtb info;
int new_dtb_count = 0;
long cur_pos = ftell(fp);
while (cur_pos < filesize) {
fgets(buff, 5, fp);
memcpy_(&info.total_size, &buff, 4); // dtb file big endian, wtf
printf("dtb block: %d, block size:%d\n", new_dtb_count, info.total_size);
info.addr_start = cur_pos - 4;
info.addr_stop = info.addr_start + info.total_size;

fseek(fp, info.addr_start, SEEK_SET);
sprintf(filename, "%s-%d", file_, new_dtb_count);
printf("%s\n", filename);
FILE *new_dtb = fopen(filename, "wb");
for (uint32_t i = 0; i < info.total_size; i++) {
buff_c = fgetc(fp);
fputc(buff_c, new_dtb);
}
fclose(new_dtb);

fseek(fp, info.addr_stop + 4, SEEK_SET); // move fp to next dtb block size
cur_pos = ftell(fp);
new_dtb_count++;
}

fclose(fp);
return 0;
}

我的目标是反编译dtb,最好能在Android直接运行。

因此上shell,本来是在x86上写调试,等最后一波在Android上再运行,无奈安卓上bash和ubuntu x86差的也太多。况且magiskboot x86 prebuilt不好用。

整个project源码见: msm8998_offset_voltage

此shell的步骤:

  1. use dd command to get boot.img
  2. use magiskboot to unpack boot.img into kernel+kernel_dtb
  3. use dtp to split kernel_dtb into sub kernel_dtb-*
  4. find the adapted dtb according to qcom, board-id and qcom, msm-id
  5. use dtc to decompile the selected dtb into .dts
  6. undervolt by change qcom,cpr-open-loop-voltage-fuse-adjustment qcom,cpr-closed-loop-voltage-fuse-adjustment qcom,cpr-closed-loop-voltage-adjustment in .dts
  7. compile dts and pack boot.img

结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[    0.440216] [    0.440200]@4 add_opp: Set OPP pair (300000000 Hz, 660000 uv) on cpu0
[ 0.440810] [ 0.440807]@4 add_opp: Set OPP pair (1900800000 Hz, 908000 uv) on cpu0
[ 0.440841] [ 0.440839]@4 add_opp: Set OPP pair (300000000 Hz, 660000 uv) on cpu1
[ 0.441210] [ 0.441208]@4 add_opp: Set OPP pair (1900800000 Hz, 908000 uv) on cpu1
[ 0.441235] [ 0.441233]@4 add_opp: Set OPP pair (300000000 Hz, 660000 uv) on cpu2
[ 0.441607] [ 0.441605]@4 add_opp: Set OPP pair (1900800000 Hz, 908000 uv) on cpu2
[ 0.441631] [ 0.441629]@4 add_opp: Set OPP pair (300000000 Hz, 660000 uv) on cpu3
[ 0.441996] [ 0.441994]@4 add_opp: Set OPP pair (1900800000 Hz, 908000 uv) on cpu3
[ 0.442028] [ 0.442026]@4 add_opp: Set OPP pair (300000000 Hz, 656000 uv) on cpu4
[ 0.442547] [ 0.442545]@4 add_opp: Set OPP pair (2457600000 Hz, 1052000 uv) on cpu4
[ 0.442578] [ 0.442576]@4 add_opp: Set OPP pair (300000000 Hz, 656000 uv) on cpu5
[ 0.443097] [ 0.443095]@4 add_opp: Set OPP pair (2457600000 Hz, 1052000 uv) on cpu5
[ 0.443120] [ 0.443117]@4 add_opp: Set OPP pair (300000000 Hz, 656000 uv) on cpu6
[ 0.443660] [ 0.443657]@4 add_opp: Set OPP pair (2457600000 Hz, 1052000 uv) on cpu6
[ 0.443685] [ 0.443682]@4 add_opp: Set OPP pair (300000000 Hz, 656000 uv) on cpu7
[ 0.444202] [ 0.444200]@4 add_opp: Set OPP pair (2457600000 Hz, 1052000 uv) on cpu7

undervolt 90mv:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[    0.454104] [    0.454088]@4 add_opp: Set OPP pair (300000000 Hz, 580000 uv) on cpu0
[ 0.454723] [ 0.454720]@4 add_opp: Set OPP pair (1900800000 Hz, 820000 uv) on cpu0
[ 0.454756] [ 0.454753]@4 add_opp: Set OPP pair (300000000 Hz, 580000 uv) on cpu1
[ 0.455132] [ 0.455130]@4 add_opp: Set OPP pair (1900800000 Hz, 820000 uv) on cpu1
[ 0.455157] [ 0.455154]@4 add_opp: Set OPP pair (300000000 Hz, 580000 uv) on cpu2
[ 0.455525] [ 0.455523]@4 add_opp: Set OPP pair (1900800000 Hz, 820000 uv) on cpu2
[ 0.455548] [ 0.455546]@4 add_opp: Set OPP pair (300000000 Hz, 580000 uv) on cpu3
[ 0.455914] [ 0.455911]@4 add_opp: Set OPP pair (1900800000 Hz, 820000 uv) on cpu3
[ 0.455948] [ 0.455946]@4 add_opp: Set OPP pair (300000000 Hz, 576000 uv) on cpu4
[ 0.456461] [ 0.456459]@4 add_opp: Set OPP pair (2457600000 Hz, 960000 uv) on cpu4
[ 0.456494] [ 0.456492]@4 add_opp: Set OPP pair (300000000 Hz, 576000 uv) on cpu5
[ 0.457025] [ 0.457023]@4 add_opp: Set OPP pair (2457600000 Hz, 960000 uv) on cpu5
[ 0.457052] [ 0.457050]@4 add_opp: Set OPP pair (300000000 Hz, 576000 uv) on cpu6
[ 0.457572] [ 0.457570]@4 add_opp: Set OPP pair (2457600000 Hz, 960000 uv) on cpu6
[ 0.457598] [ 0.457596]@4 add_opp: Set OPP pair (300000000 Hz, 576000 uv) on cpu7
[ 0.458135] [ 0.458133]@4 add_opp: Set OPP pair (2457600000 Hz, 960000 uv) on cpu7

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×