0%

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
/****************************************************************************/ /**
* @brief Efuse lock reading for aes key
*
* @param index: index of key slot
* @param program: program to efuse entity or not
*
* @return None
*
*******************************************************************************/
void EF_Ctrl_Readlock_AES_Key(uint8_t index, uint8_t program)
{
uint32_t tmpVal;

if (index > 5) {
return;
}

/* Switch to AHB clock */
EF_Ctrl_Sw_AHB_Clk_0();

tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_LOCK);
tmpVal |= (1 << (index + 26));
BL_WR_REG(EF_DATA_BASE, EF_DATA_0_LOCK, tmpVal);

if (program) {
EF_Ctrl_Program_Efuse_0();
}
}

/****************************************************************************/ /**
* @brief Efuse write AES key
*
* @param index: index of key slot
* @param keyData: key data buffer
* @param len: key data length in words
* @param program: program to efuse entity or not
*
* @return None
*
*******************************************************************************/
void EF_Ctrl_Write_AES_Key(uint8_t index, uint32_t *keyData, uint32_t len, uint8_t program)
{
uint32_t *pAESKeyStart0 = (uint32_t *)(EF_DATA_BASE + 0x1C);

if (index > 5) {
return;
}

/* Switch to AHB clock */
EF_Ctrl_Sw_AHB_Clk_0();

/* Every key is 4 words len*/
BL702_MemCpy4(pAESKeyStart0 + index * 4, keyData, len);

if (program) {
EF_Ctrl_Program_Efuse_0();
}
}

代码示例:

假设key为

1
2
3
4
5
6
7
8
9
10
11
12
uint32_t *keyData = {
0x41cb3b9a,
0x7cf9f7cf,
0xdc0dd12f,
0x6c3ed53a,
0x00a0c824,
0xc737923e,
0xe2f055f1,
0x34afa0f7,
}
// 写入key_slot2 key_slot3
EF_Ctrl_Write_AES_Key(2, keyData, 8, 1);

先做实验, 验证key_slot2, key_slot3 是否正常写入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/****************************************************************************/ /**
* @brief Efuse read AES key from specified region and index
*
* @param index: index of key slot
* @param keyData: key data buffer
* @param len: key data length in words
*
* @return None
*
*******************************************************************************/
void EF_Ctrl_Read_AES_Key(uint8_t index, uint32_t *keyData, uint32_t len)
{
uint32_t *pAESKeyStart0 = (uint32_t *)(EF_DATA_BASE + 0x1C);

if (index > 5) {
return;
}

/* Trigger read data from efuse*/
EF_CTRL_LOAD_BEFORE_READ_R0;

/* Every key is 4 words len*/
BL702_MemCpy4(keyData, pAESKeyStart0 + index * 4, len);
}

示例代码, 读取key_slot2, key_slot3的key数据

1
2
uint32_t keyRead[8] = {0};
EF_Ctrl_Read_AES_Key(2, keyRead, 8);

判断keyRead 与 keyData 是否一致

如果前面写入正常, 最后需要对key_slot2, key_slot3 做读保护

阅读全文 »

MIPS 相关理解

协处理器

在MIPS体系结构中,最多支持4个协处理器(Co-Processor)。其中,协处理器CP0是体系结构中必须实现的。它起到控制CPU的作用。MMU、异常处理、乘除法等功能,都依赖于协处理器CP0来实现。它是MIPS的精髓之一,也是打开MIPS特权级模式的大门。

   - Register 0: Index,作为MMU的索引用。将来讨论MMU和TLB时会详解之。
   - Register 2, EntryLo0,访问TLB Entry偶数页中的地址低32Bit用。同上,在MMU和TLB的相关章节中详解。
   - Register 3, EntryLo1,访问TLB Entry奇数页中的地址低32Bit用。
   - Register 4, Context,用以加速TLB Miss异常的处理。
   - Register 5, PageMask,用以在MMU中分配可变大小的内存页。
   - Register 8, BadVAddr,在系统捕获到TLB Miss或Address Error这两种Exception时,发生错误的虚拟地址会储存在该寄存器中。对于引发Exception的Bug的定位来说,这个寄存器非常重要。
   - `Register 9`, Count,这个寄存器是R4000以后的MIPS系统引入的。它是一个计数器,`计数频率是系统主频的1/2`。BCM1125/1250,RMI XLR系列以及Octeon的Cavium处理器均支持该寄存器。对于操作系统来说,`可以通过读取该寄存器的值来获取tick的时基`。`在系统性能测试中,利用该寄存器也可以实现打点计数`。
   - Register 10,EntryHi,这个寄存器同EntryLo0/1一样,用于MMU中。以后会详述。
   - Register 11,Compare,配合Count使用。当Compare和Count的值相等的时候,会触发一个硬件中断(Hardware Interrupt),并且总是使用Cause寄存器的IP7位。  
   - Register 12,Status,用于处理器状态的控制。
   - Register 13,Cause,这个寄存器体现了处理器异常发生的原因。
   -   Register 14,EPC,这个寄存器存放异常发生时,系统正在执行的指令的地址。
   -   Register 15,PRID,这个寄存器是只读的,标识处理器的版本信息。向其中写入无意义。
  •   Register 18/19,WatchLo/WatchHi,这对寄存器用于设置硬件数据断点(Hardware Data Breakpoint)。该断点一旦设定,当CPU存取这个地址时,系统就会发生一个异常。这个功能广泛应用于调试定位内存写坏的错误。
      Register 28/29,TagLo和TagHi,用于高速缓存(Cache)管理。

相关链接 协处理器CP0

常用汇编指令

MFC0、MTC0、DMFC0、DMTC0可以完成通用寄存器和CP0寄存器之间的数据传送。比如我们可以通过下面指令来获取epc寄存器的值。

             mfc0 t1,$14           # 从CP0 取epc寄存器($14)数据,存到通用寄存器t0

mfc0完成从cp0寄存器获取一个32位数据(如果cp0寄存器是64位数据则只取其低32位。)到通用寄存器,如果要获取的是64位数据则需要使用dmfc0指令。

阅读全文 »

ARMv8 有 el0-el3 四个异常等级, 有 NS 和 S 两个状态, ARMv8 对 TZ 技术有先天性的优势.

ARMv7 基础

在 armv7 上首次添加了 trustzone, 在 arm 原有七种运行模式的基础上扩展出了 monitor 模式
normal world 和 sec world 的切换是由 monitor 模式下的程序来完成.

arm 原有的其中运行模式

  • usr 模式(用户模式): 正常程序运行时的模式
  • fiq 模式(快速中断模式): 当配置有快速中断时, 如果产生 fiq 事件, arm 会切换到该模式
  • irq 模式(用户模式): 中断模式, 用于通用中断处理, 被 ROS 使用
  • svc 模式(管理模式): 操作系统使用的保护模式
  • abt 模式(数据访问终止模式): 当数据或者指令取值时终止则会进入该模式
  • und 模式(未定义指令模式): 当未定义指令执行会进入该模式
  • sys 模式(系统模式): 运行具有特权的操作系统任务

这些模式都是一种硬件反应态,AXI 总线强烈依赖访问时的模式。
支持 TZ 后, ARM 增加了 monitor 模式. monitor 模式是共享的, 在 monitor 模式下, 每种状态具有独立的七种模式

armv7 安全位扩展

在支持 TZ 后, ARM 在 axi 总线上增加了一个 NS 位(安全状态位), 用来标识当前的数据\指令是属于安全世界还是非安全世界, NS bit 保存在 scr 寄存器的 0 bit, NS=1, normal world, NS=0, sec world

除了对总线进行扩展之外,ARM 对 MMU 和 Cache 也同样进行了安全状态位的扩展,用于标记 MMU 中存放的物理内存映射后的地址是属于安全内存地址还是非安全地址,而对于 Cache 该位会被用来标记当前的 Cache 是属于安全态的 Cache 还是非安全态的 Cache。当 ARM 核访问物理地址时,会对该虚拟地址的安全状态位进行检查,而在访问物理内存时安全扩展组件会对地址进行权限检查,该权限检查操作属于硬件级别的检查,不受软件的控制。关于安全地址的配置则是在 IC 设计时通过配置安全组件的参数来设定的

阅读全文 »

芯片上

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
   0xbfc01000:  move    a2,t2
=> 0xbfc01004: lw a0,0(s0)
0xbfc01008: move a2,t2
0xbfc0100c: jal 0xbfc00a64
0xbfc01010: move a1,t3
0xbfc01014: bnez v0,0xbfc010a8
0xbfc01018: li a2,100
0xbfc0101c: li a1,4

0xbfc01000: jal 0xbfc00a64
0xbfc01004: lw a0,0(s0)
=> 0xbfc01008: move a2,t2
0xbfc0100c: jal 0xbfc00a64
0xbfc01010: move a1,t3
0xbfc01014: bnez v0,0xbfc010a8
0xbfc01018: li a2,100
0xbfc0101c: li a1,4


0xbfc01000: move a1,t3
0xbfc01004: lw a0,0(s0)
0xbfc01008: move a2,t2
=> 0xbfc0100c: jal 0xbfc00a64
0xbfc01010: move a1,t3
0xbfc01014: bnez v0,0xbfc010a8
0xbfc01018: li a2,100
0xbfc0101c: li a1,4

下载模式下调试

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
	la a2,		change_k0_cca
li a1, 0xf
ins a2, a1, 29, 1 // changed to KSEG1 address by setting bit 29
jalr a2


LEAF(change_k0_cca)
// NOTE! This code must be executed in KSEG1 (not KSGE0 uncached)
// Set CCA for kseg0 to cacheable
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
mfc0 TEMP1, C0_CONFIG // read C0_Config
li TEMP2, 2 // CCA for all others

set_kseg0_cca:
ins TEMP1, TEMP2, 0, 3 // insert K0
mtc0 TEMP1, C0_CONFIG // write C0_Config
ehb
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
jalr.hb zero, ra

END(change_k0_cca)
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
Remote debugging using 192.168.66.149:3333
warning: No executable has been specified and target does not support
determining executable automatically. Try using the "file" command.
0x82c0ee7c in ?? ()
Undefined command: "dashboard". Try "help".
Loading section .text_init, size 0x2540 lma 0x84104000
Loading section .text_ram, size 0x4628 lma 0x84106540
Loading section .rodata, size 0xa10 lma 0x8410ab68
Loading section .data, size 0x28 lma 0x8410b578
Start address 0x84104000, load size 30112
Transfer rate: 21 KB/sec, 6022 bytes/write.
Execution start_address = 0x84104000
Fastdata access Failed
Falling back to non-bulk write
46496 bytes written at address 0x84100000
downloaded 46496 bytes in 3.464504s (13.106 KiB/s)
target was already halted
Breakpoint 1 at 0x84104000: file src/asm/start.S, line 46.
Continuing.

Program stopped.
__reset_vector () at src/asm/start.S:46
46 la a2, check_nmi
(gdb) disassemble change_k0_cca
Dump of assembler code for function change_k0_cca:
0x84104804 <+0>: nop
0x84104808 <+4>: nop
0x8410480c <+8>: nop
0x84104810 <+12>: nop
0x84104814 <+16>: nop
0x84104818 <+20>: nop
0x8410481c <+24>: nop
0x84104820 <+28>: nop
0x84104824 <+32>: nop
0x84104828 <+36>: nop
0x8410482c <+40>: nop
0x84104830 <+44>: nop
0x84104834 <+48>: nop
0x84104838 <+52>: nop
0x8410483c <+56>: nop
0x84104840 <+60>: nop
0x84104844 <+64>: nop
0x84104848 <+68>: nop
0x8410484c <+72>: nop
0x84104850 <+76>: nop
0x84104854 <+80>: mfc0 t6,c0_config
0x84104858 <+84>: li t7,2
0x8410485c <+88>: ins t6,t7,0x0,0x3
0x84104860 <+92>: mtc0 t6,c0_config
0x84104864 <+96>: ehb
0x84104868 <+100>: nop
0x8410486c <+104>: nop
0x84104870 <+108>: nop
0x84104874 <+112>: nop
0x84104878 <+116>: nop
0x8410487c <+120>: nop
0x84104880 <+124>: nop
0x84104884 <+128>: nop
0x84104888 <+132>: nop
0x8410488c <+136>: nop
0x84104890 <+140>: nop
0x84104894 <+144>: nop
0x84104898 <+148>: nop
0x8410489c <+152>: nop
0x841048a0 <+156>: nop
0x841048a4 <+160>: nop
0x841048a8 <+164>: nop
0x841048ac <+168>: nop
0x841048b0 <+172>: nop
0x841048b4 <+176>: nop
0x841048b8 <+180>: jalr.hb zero,ra
0x841048bc <+184>: nop
End of assembler dump.
(gdb) b *0xa410486c
Breakpoint 2 at 0xa410486c
(gdb) c
Continuing.

Program stopped.
0xa410486c in ?? ()
(gdb) mon mips32 cp0 config
0xa4310582
(gdb) mon mww 0x82d030b4 0x80000080
(gdb) x/12i 0xbfc00100
0xbfc00100: sdc2 $16,147(k1)
0xbfc00104: ldc1 $f7,16913(ra)
0xbfc00108: sw gp,-16950(a0)
0xbfc0010c: 0x7f9f292a
0xbfc00110: jalx 0xb02f4ffd
0xbfc00114: 0x720b0904
0xbfc00118: 0x6082ee6e
0xbfc0011c: lwc2 $15,4232(t7)
0xbfc00120: lwc1 $f1,-17410(a2)
0xbfc00124: ldc2 $13,-24540(t7)
0xbfc00128: ll t7,-9333(t0)
0xbfc0012c: 0x1feb0088
(gdb) restore ~/work_space/benji/splfdl/text_init.bin binary 0xbfc00100
Restoring binary file /home/liguang/work_space/benji/splfdl/text_init.bin into memory (0xffffffffbfc00100 to 0xffffffffbfc03e40)
(gdb) x/12i 0xbfc00100
0xbfc00100: lui a2,0x82a0
0xbfc00104: addiu a2,a2,1172
0xbfc00108: jr a2
0xbfc0010c: mtc0 zero,c0_count
0xbfc00110: nop
0xbfc00114: nop
0xbfc00118: nop
0xbfc0011c: nop
0xbfc00120: nop
0xbfc00124: nop
0xbfc00128: nop
0xbfc0012c: nop
(gdb) mon mww 0x82d030b4 0x80
(gdb) x/12i 0xbfc00100
0xbfc00100: lui a2,0x82a0
0xbfc00104: addiu a2,a2,1172
0xbfc00108: jr a2
0xbfc0010c: mtc0 zero,c0_count
0xbfc00110: nop
0xbfc00114: nop
0xbfc00118: nop
0xbfc0011c: nop
0xbfc00120: nop
0xbfc00124: nop
0xbfc00128: nop
0xbfc0012c: nop
(gdb) b *0xbfc00100
warning: GDB can't find the start of the function at 0xa410486c.

GDB is unable to find the start of the function at 0xa410486c
and thus can't determine the size of that function's stack frame.
This means that GDB may be unable to access that stack frame, or
the frames below it.
This problem is most likely caused by an invalid program counter or
stack pointer.
However, if you think GDB should simply search farther back
from 0xa410486c for code which looks like the beginning of a
function, you can increase the range of the search using the `set
heuristic-fence-post' command.
Breakpoint 3 at 0xbfc00100
(gdb) x/12i 0xbfc00100
0xbfc00100: lui a2,0x82a0
0xbfc00104: addiu a2,a2,1172
0xbfc00108: jr a2
0xbfc0010c: mtc0 zero,c0_count
0xbfc00110: nop
0xbfc00114: nop
0xbfc00118: nop
0xbfc0011c: nop
0xbfc00120: nop
0xbfc00124: nop
0xbfc00128: nop
0xbfc0012c: nop
(gdb) j *0xbfc00100
Continuing at 0xbfc00100.

Program stopped.
0xbfc00100 in ?? ()
(gdb) x/12i 0xbfc00100
=> 0xbfc00100: 0xf06275ff
0xbfc00104: 0xf06275ff
0xbfc00108: 0xf06275ff
0xbfc0010c: 0xf06275ff
0xbfc00110: 0xf06275ff
0xbfc00114: 0xf06275ff
0xbfc00118: 0xf06275ff
0xbfc0011c: 0xf06275ff
0xbfc00120: 0xf06275ff
0xbfc00124: 0xf06275ff
0xbfc00128: 0xf06275ff
0xbfc0012c: 0xf06275ff

fpga验证

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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
❯ mgdb.microAptiv 8888
GNU gdb (GDB) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "--host=x86_64-pc-linux-gnu --target=mips-mti-elf".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word".
Remote debugging using localhost:7777
warning: No executable has been specified and target does not support
determining executable automatically. Try using the "file" command.
0x00000000 in ?? ()
The target is assumed to be little endian
target state: halted
target halted in MIPS32 mode due to debug-request, pc: 0x82c476d8
"on" or "off" expected.
(microAptiv) mon mips32 cp0 config
0xa4310582
(microAptiv) x/i $pc
=> 0x0: nop
(microAptiv) x/i $pc
=> 0x0: nop
(microAptiv) mon mww 0xa2a00008 0x7ca41004
(microAptiv) mon mww 0xa2a00000 0x40048000
(microAptiv) mon mww 0xa2a00004 0x24050003
(microAptiv) mon mww 0xa2a0000c 0x40848000
(microAptiv) x/8i 0xa2a00000
0xa2a00000: mfc0 t6,$16
0xa2a00004: li t7,3
0xa2a00008: 0x7dee1004
0xa2a0000c: mtc0 t6,$16
0xa2a00010: nop
0xa2a00014: nop
0xa2a00018: nop
0xa2a0001c: nop
=> (microAptiv) b *0xa2a00000
Breakpoint 1 at 0xa2a00000
==> (microAptiv) j *0xa2a00000
Continuing at 0xa2a00000.

Program stopped.
0xa2a00000 in ?? ()
(microAptiv) disassemble 0xa2a00000,+0x20
Dump of assembler code from 0xa2a00000 to 0xa2a00020:
=> 0xa2a00000: mfc0 a0,$16
0xa2a00004: li a1,3
0xa2a00008: 0x7ca41004
0xa2a0000c: mtc0 a0,$16
0xa2a00010: nop
0xa2a00014: nop
0xa2a00018: nop
0xa2a0001c: nop
End of assembler dump.
(microAptiv) ni
warning: GDB can't find the start of the function at 0xa2a00000.

GDB is unable to find the start of the function at 0xa2a00000
and thus can't determine the size of that function's stack frame.
This means that GDB may be unable to access that stack frame, or
the frames below it.
This problem is most likely caused by an invalid program counter or
stack pointer.
However, if you think GDB should simply search farther back
from 0xa2a00000 for code which looks like the beginning of a
function, you can increase the range of the search using the `set
heuristic-fence-post' command.
warning: GDB can't find the start of the function at 0xa2a00004.
0xa2a00004 in ?? ()
(microAptiv) ni
warning: GDB can't find the start of the function at 0xa2a00008.
0xa2a00008 in ?? ()
(microAptiv) ni
warning: GDB can't find the start of the function at 0xa2a0000c.
0xa2a0000c in ?? ()
(microAptiv) i r a0
a0: 0xa4310583
(microAptiv) ni
warning: GDB can't find the start of the function at 0xa2a00010.
0xa2a00010 in ?? ()
(microAptiv) mon mips32 cp0 config
0xa4310583
(microAptiv) disassemble 0xa2a00000,+0x20
Dump of assembler code from 0xa2a00000 to 0xa2a00020:
0xa2a00000: mfc0 a0,$16
0xa2a00004: li a1,3
0xa2a00008: 0x7ca41004
0xa2a0000c: mtc0 a0,$16
=> 0xa2a00010: nop
0xa2a00014: nop
0xa2a00018: nop
0xa2a0001c: nop
End of assembler dump.
(microAptiv) mon mww 0x82d030b4 0x80000080
(microAptiv) restore ~/work_space/benji/splfdl/text_init.bin binary 0xbfc00100
Restoring binary file /home/liguang/work_space/benji/splfdl/text_init.bin into memory (0xffffffffbfc00100 to 0xffffffffbfc03cb0)
(microAptiv) x/8i 0xbfc00100
0xbfc00100: lui a2,0xbfc0
0xbfc00104: addiu a2,a2,1172
0xbfc00108: jr a2
0xbfc0010c: mtc0 zero,$9
0xbfc00110: nop
0xbfc00114: nop
0xbfc00118: nop
0xbfc0011c: nop
(microAptiv) mon mww 0x82d030b4 0x80
(microAptiv) b *0xbfc00100
Breakpoint 2 at 0xbfc00100
(microAptiv) j *0xbfc00100
Continuing at 0xbfc00100.

Program stopped.
0xbfc00100 in ?? ()
(microAptiv) mon mips32 cp0 config
0xa4310583
(microAptiv) x/12i $pc
=> 0xbfc00100: lui a2,0xbfc0
0xbfc00104: addiu a2,a2,1172
0xbfc00108: jr a2
0xbfc0010c: mtc0 zero,$9
0xbfc00110: nop
0xbfc00114: nop
0xbfc00118: nop
0xbfc0011c: nop
0xbfc00120: nop
0xbfc00124: nop
0xbfc00128: nop
0xbfc0012c: nop
(microAptiv) x/12i 0xbfc00100
=> 0xbfc00100: lui a2,0xbfc0
0xbfc00104: addiu a2,a2,1172
0xbfc00108: jr a2
0xbfc0010c: mtc0 zero,$9
0xbfc00110: nop
0xbfc00114: nop
0xbfc00118: nop
0xbfc0011c: nop
0xbfc00120: nop
0xbfc00124: nop
0xbfc00128: nop
0xbfc0012c: nop
(microAptiv) ni
warning: GDB can't find the start of the function at 0xbfc00100.
warning: GDB can't find the start of the function at 0xbfc00104.
0xbfc00104 in ?? ()
(microAptiv) x/12i 0xbfc00100
0xbfc00100: lui a2,0xbfc0
=> 0xbfc00104: addiu a2,a2,1172
0xbfc00108: jr a2
0xbfc0010c: mtc0 zero,$9
0xbfc00110: nop
0xbfc00114: nop
0xbfc00118: nop
0xbfc0011c: nop
0xbfc00120: nop
0xbfc00124: nop
0xbfc00128: nop
0xbfc0012c: nop
(microAptiv) file ~/u
uA_baremetal.elf uAptiv_Baremetal.elf ua.bin
(microAptiv) file ~/uA_baremetal.elf
Reading symbols from ~/uA_baremetal.elf...
warning: GDB can't find the start of the function at 0xbfc00104.
(microAptiv) restore ~/u
uA_baremetal.elf uAptiv_Baremetal.elf ua.bin
(microAptiv) restore ~/work_space/benji/xy-bootrom/objs_release/uA_baremetal.bin binary 0x82c00000
Restoring binary file /home/liguang/work_space/benji/xy-bootrom/objs_release/uA_baremetal.bin into memory (0xffffffff82c00000 to 0xffffffff82c1147f)
(microAptiv) x/8i 0x82c00000
0x82c00000 <__reset_vector at src/startup/start.S:41>: lui a2,0x82c0
0x82c00004 <__reset_vector+4 at src/startup/start.S:41>: addiu a2,a2,1280
0x82c00008 <__reset_vector+8 at src/startup/start.S:43>: jr a2
0x82c0000c <__reset_vector+12 at src/startup/start.S:43>: mtc0 zero,c0_count
0x82c00010 <_boot_rom+16 at src/startup/start.S:43>: nop
0x82c00014 <_boot_rom+20 at src/startup/start.S:43>: nop
0x82c00018 <_boot_rom+24 at src/startup/start.S:43>: nop
0x82c0001c <_boot_rom+28 at src/startup/start.S:43>: nop
(microAptiv) b *0x82c00000
Breakpoint 3 at 0x82c00000: file src/startup/start.S, line 41.
(microAptiv) j *0x82c00000
Continuing at 0x82c00000.

Program stopped.
__reset_vector () at src/startup/start.S:41
41 la a2, check_nmi
(microAptiv) ni
0x82c00004 41 la a2, check_nmi
(microAptiv) x/12i 0xbfc00000
0xbfc00000: lui a2,0x82c0
0xbfc00004: addiu a2,a2,0
0xbfc00008: jr a2
0xbfc0000c: nop
0xbfc00010: nop
0xbfc00014: nop
0xbfc00018: nop
0xbfc0001c: nop
0xbfc00020: nop
0xbfc00024: nop
0xbfc00028: nop
0xbfc0002c: nop
(microAptiv) x/12i 0xbfc00100
0xbfc00100: lui a2,0xbfc0
0xbfc00104: addiu a2,a2,1172
0xbfc00108: jr a2
0xbfc0010c: mtc0 zero,c0_count
0xbfc00110: nop
0xbfc00114: nop
0xbfc00118: nop
0xbfc0011c: nop
0xbfc00120: nop
0xbfc00124: nop
0xbfc00128: nop
0xbfc0012c: nop
(microAptiv) ni
43 jr a2
(microAptiv) x/8i $pc
=> 0x82c00008 <__reset_vector+8 at src/startup/start.S:43>: jr a2
0x82c0000c <__reset_vector+12 at src/startup/start.S:43>: mtc0 zero,c0_count
0x82c00010 <_boot_rom+16 at src/startup/start.S:43>: nop
0x82c00014 <_boot_rom+20 at src/startup/start.S:43>: nop
0x82c00018 <_boot_rom+24 at src/startup/start.S:43>: nop
0x82c0001c <_boot_rom+28 at src/startup/start.S:43>: nop
0x82c00020 <_boot_rom+32 at src/startup/start.S:43>: nop
0x82c00024 <_boot_rom+36 at src/startup/start.S:43>: nop
(microAptiv) x/12i 0xbfc00100
0xbfc00100: lui a2,0xbfc0
0xbfc00104: addiu a2,a2,1172
0xbfc00108: jr a2
0xbfc0010c: mtc0 zero,c0_count
0xbfc00110: nop
0xbfc00114: nop
0xbfc00118: nop
0xbfc0011c: nop
0xbfc00120: nop
0xbfc00124: nop
0xbfc00128: nop
0xbfc0012c: nop
(microAptiv) b *0xbfc00100
Note: breakpoint 2 also set at pc 0xbfc00100.
Breakpoint 4 at 0xbfc00100
(microAptiv) j *0xbfc00100
Continuing at 0xbfc00100.

Program stopped.
0xbfc00100 in ?? ()
(microAptiv) ni
warning: GDB can't find the start of the function at 0xbfc00100.
warning: GDB can't find the start of the function at 0xbfc00104.
0xbfc00104 in ?? ()
(microAptiv) x/12i 0xbfc00100
0xbfc00100: lui a2,0xbfc0
=> 0xbfc00104: addiu a2,a2,1172
0xbfc00108: jr a2
0xbfc0010c: mtc0 zero,c0_count
0xbfc00110: nop
0xbfc00114: nop
0xbfc00118: nop
0xbfc0011c: nop
0xbfc00120: nop
0xbfc00124: nop
0xbfc00128: nop
0xbfc0012c: nop
(microAptiv)
1
2
3
test 按下
The CRU Status regs are: 0x5801 0x3347
The CRU Status regs are: 0x1 0x3347
阅读全文 »

Qcow2 qemu 打包日记

1
2
3
4
5
6
7
8
9
10
11
12
13
modprobe nbd
qemu-img create -f qcow2 image.qcow2 1G
sudo qemu-nbd --connect=/dev/nbd0 image.qcow2
sudo sgdisk -g --clear -a 1 \
--new=1:34:2081         --change-name=1:spl --typecode=1:5B193300-FC78-40CD-8002-E86C45580B47 \
--new=2:2082:10273      --change-name=2:uboot  --typecode=2:2E54B353-1271-4842-806F-E436D6AF6985 \
--new=3:16384:282623    --change-name=3:boot --typecode=3:0x8300 \
  /dev/nbd0
sudo dd if=<u-boot_root_path/build/u-boot.itb> of=/dev/nbd0p2   "将u-boot.itb 拷贝到sd卡的第二个分区"
sudo mkfs.ext4 /dev/nbd0p3
sudo mount /dev/nbd0p3 <mnt_dir>
cp Image wave,boston-kingv.dtb <mnt_dir> "Image 为 kernel 编译出的 <build>/arch/riscv/boot/Image, dtb 为kernel 用的dtb"
sudo umount <mnt_dir> sudo qemu-nbd --disconnect /dev/nbd0

制作分区

1
2
3
4
5
6
sudo sgdisk -g --clear -a 1 \
--new=1:34:2081 --change-name=1:spl --typecode=1:5B193300-FC78-40CD-8002-E86C45580B47 \
--new=2:2082:10273 --change-name=2:uboot --typecode=2:2E54B353-1271-4842-806F-E436D6AF6985 \
--new=3:16384:282623 --change-name=3:boot --typecode=3:0x0700 \
--new=4:286720:2018207 --change-name=4:root --typecode=4:0x8300 \
test.img

挂载

1
2
3
sudo fdisk -l test.img
sudo losetup -f --show -P test.img
sudo mount /dev/loopXpX mnt

无卡启动

配置tftpd

1
2
3
4
5
6
7
8
9
10
sudo apt install tftpd-hpa
sudo vi /etc/default/tftpd-hpa #编辑 /etc/default/tftpd-hpa
# /etc/default/tftpd-hpa

TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS=":69"
TFTP_OPTIONS="-s"

sudo chmod 777 -R /srv/tftp

配置完后, tftp 使用的目录为 /srv/tftp

阅读全文 »

签名

签名文件

1
.\sign_file.exe -d -r .\driver_test_key\ecc_priv_key -b <待签文件路径> -e <签名后的文件路径> -s

验证是否验签正常

1
.\sign_file.exe -d -u .\driver_test_key\ecc_pub_key  -e <签名后的文件路径> -v

验签

验签接口 verifyFile

1
2
3
4
5
6
7
8
9
10
#pragma once
/*
* ecc verify file to check if sign by specific priv key
* input:
* fp: input file pointer by fopen
* fileSize: file size by stat.st_size
* out:
* return 0: verify success, -1: verify fail
*/
int verifyFile(FILE* fp, int fileSize);

上面的实现代码就是VerifyLibApi.h的内容

使用示例

阅读全文 »

蒙哥马利算法(Montgomery Algorithm)|蒙哥马利约简、模乘

模乘是为了计算ab(mod M)。普通算法中,在计算模M时,利用的是带余除法,除法运算需要太多次乘法,计算复杂度较高

蒙哥马利算法的思想就是利用进制表示简化除法运算,转化成位运算。

给定大数 a, b. 素数模 m

目的是求 Z = ab(mod m)

转化为蒙哥马利域算式:

先计算 aR(mod m), bR(mod m), 其中R=2^k, k=log2(m)

第一次蒙哥马利约简:

Z’= aR * bR * R^-1 (mod m) = abR(mod m) (1)

第二次蒙哥马利约简:

阅读全文 »

buildroot 编译 cryptsetup

需要编译依赖包: libdevmapper libpopt libuuid libjson-c libcrypto (openssl包)
嵌入式平台编译比较麻烦, 交叉工具链会报很多头文件 库文件的错误, 建议直接由buildroot编译交叉工具链, 这样后续生成的库文件 头文件才能正常找到, 还有cmake 用到的.cmake 包, pkgconfig的路径等.

最终生成文件 cryptsetup veritysetup dmsetup libcryptsetup.so

测试

1
2
3
4
5
6
mkfs.ext4 -b 4096 fs.img 4096
veritysetup format fs.img hashtree.img
#as: Root hash: d004843ab1abc42dbdcf320b7189d871536cdf6e5e6e2c03c2c0fd20dfc2fe9a
记下$root_hash
veritysetup create vroot fs.img hashtree.img $root_hash
mount /dev/mapper/vroot mount_point

编译kernel 支持dm-verity

1
2
3
4
5
make menuconfig
# Find the following options in the menuconfig and change them as described:
# Device Drivers → Multiple devices driver support (RAID and LVM) → Device mapper support → change to * (YES)
# Device Drivers → Multiple devices driver support (RAID and LVM) → Device mapper support → DM "dm-mod.create=" parameter support → change to * (YES)
# Device Drivers → Multiple devices driver support (RAID and LVM) → Device mapper support → Verity target support → change to * (YES)

kernel 调试

去掉优化

子模块中的Makefile可以通过CFLAGS_xxx.o += -O0 去掉某个源文件的编译优化
但还是有很多文件不支持 -O0 编译, 可以再细分, 按函数就行 -O0 编译
__attribute__((optimize("O0")))

阅读全文 »

stm32_750

中断耗时 29264

算法 数据量 耗时 数据量 耗时
aes-cbc-128 40k 199368 64k (342000+291048)/2-29264=287260
aes-cbc-192 40k 178104 64k (323104+291408)/2-29264=277992
aes-cbc-256 40k 161520 64k (294192+271480)/2-29264=253572
sha2-224 40k 190392-28120+5904 = 168176 64k 287528-28120+5904 = 265312
sha2-256 40k 189904-28102+5776 = 167578 64k 286184-28102+5776 = 263858
crc32 (0x04C11DB7) 40k 140136 64k 223754
crc16-ccitt 40k 142600 64k 223853
crc8-ccitt 40k 139858 64k 223461
TRNG 40k 1130608 64k 1793120

sha2-256 4k 43504+21264-28120= 36648

1
2
c "1/(480*1000*1000) * 36648" = 0.00007 s //for hash-256 4k
c "1/(480*1000*1000) * 167578 / 40 * 1024" = 0.009s

1M 数据时间

1
2
3
c "1/(480*1000*1000)*(199368)/40*1024" = 0.01s   //aes-128 750
c "1/(400*1000*1000)*(626550)/40*1024" = 0.04s // aes-256 cip
c "1/(400*1000*1000)*(1002480/64)*1024" = 0.04s // aes-256 cip
1
2
c "64*1024*8/1793120" = 0.3 bit/cycle    //trng
c "1/(480*1000*1000) * 167578" = 0.00035s //sha-256 40k

CIP_1901

算法 数据量 耗时 数据量 耗时
aes-cbc-128 40k 462550 64k 740032
aes-cbc-256 40k 626550 64k 1002480
sha2-256 40k 174700 64k 279268 512k 2237620
sha2-384 40k 113784 64k 181788 512k 1518852
crc32 (0x04C11DB7) 40k 128204 64k 204158
crc16-ccitt 40k 129834 64k 205702
crc8-ccitt 40k 128184 64k 204164
ecc-192-sign 16 609418
ECC-224-sign 16 745262
ECC-256-sign 16 870176
ECC-384-sign 16 1571708
ECC-192-verify 16 6753310
ECC-224-verify 16 8529408
ECC-256-verify 16 11227626
ECC-384-verify 16 25775968
ECC-256-sign 32 870134
ECC-384-sign 32 1571634
ECC-256-verify 32 11489984
ECC-384-verify 32 26295924
Ecc-384-sign 48 1571480
ECC-384-verify 48 25897978
阅读全文 »

生成从flash启动的文件

boot模式启动后自动运行

烧写规范

目前仅支持烧写spl fdl 和 大核的bin, ua-validation的bin 只能先伪装成spl来测试boot流程.

romcode 固化的代码中将spl下载到了ahbsram区域, 因此ua的bin也会下载到ahbsram上, 最大只能到128k

小核镜像打包

当前只能做普通非加密模式的bin, ua-validation生成的产物

  • validation/uAptiv_Baremetal.elf  

  • validation/uAptiv_Baremetal.bin 未做header包裹的bin, 不能直接用

  • validation/spl_non_sec.bin 生成了header, 可以作为spl烧写到flash 中, 给到烧机工具, 填到spl槽位

单独打包小核镜像

本节没有特殊需求, 可以不用看

如果需要根据uAptiv_Baremetal.elf文件重新打包出能烧写到flash中的符合规范的bin, 请参考下面的步骤:

在代码根目录下:

1
2
3
4
5
6
7

cd validation;

mips-mti-elf-objcopy -O binary uAptiv_Baremetal.elf uAptiv_Baremetal.bin

../tools/sign_tool.py -n --ua --source . --out .

生成的文件spl_non_sec.bin 给到烧机工具即可

如果没有单独打包小核镜像的需求, 单独打包小核镜像 小节直接忽略就行, 默认编译结果已经包含

大核镜像打包

当前只能做普通非加密模式的bin, ia-validation生成的产物

  • ia-validation/iAptiv_Baremetal.elf

  • ia-validation/iAptiv_Baremetal.bin  未做header包裹的bin, 不能直接用

  • ia-validation/ia_non_sec.bin        生成了header, 可以作为ia烧写到flash 中, 给到烧机工具, 填到ia槽位

单独打包大核镜像

本节没有特殊需求, 可以不用看

如果需要根据iAptiv_Baremetal.elf文件重新打包出能烧写到flash中的符合规范的bin, 请参考下面的步骤:

在代码根目录下:

1
2
3
4
5
6
7
8
9
10
11

cd ia-validation;

mips-mti-elf-objcopy -R .text_init -O binary iAptiv_Baremetal.elf iAptiv_Baremetal_App.bin

mips-mti-elf-objcopy -j .text_init -O binary iAptiv_Baremetal.elf iAptiv_Baremetal_Boot.bin

cat iAptiv_Baremetal_Boot.bin iAptiv_Baremetal_App.bin > iAptiv_Baremetal.bin

../tools/sign_tool.py -n --ia --source . --out .

生成的文件ia_non_sec.bin 给到烧机工具即可

如果没有单独打包大核镜像的需求,  单独打包大核镜像小节 直接忽略就行, 默认编译结果已经包含

烧写大核启动镜像

启动到大核需要spl转接, 不是上面 ua-validation, 下载这里的spl_non_sec_real.bin

烧写大核时需要同时把 fdl spl (spl_non_sec_real.bin) 和 当前编出的大核的bin(ia_non_sec.bin) 烧入对应槽

2230995-20210517010440573-253963743

阅读全文 »