你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

uboot的升级中比较有意思的两个问题

[复制链接]
gaosmile 发布时间:2020-9-11 15:02
背景
5 T% U7 e" F( c# |" S% H

6 d% c* A/ i! @: c5 Z% J之前做过一次uboot的升级,当时留下了一些记录,本文摘录其中比较有意思的两个问题。% K2 H1 V" \% n6 @& {

" @5 ?# J- J: v8 p& @% P
" ^4 E0 g% m1 g1 \4 e4 {
启动失败问题( N# E3 [1 w4 l) W2 i- k! I8 a# v
问题简述6 q, j0 N3 a, h  g( q
uboot代码中用到了一个库,考虑到库本身跟uboot版本没什么关系,就直接把旧的库文件拷贝过来使用。结果编译链接是没问题,启动却会卡住。
0 i4 K! L' V: y' i2 \, T5 V. c" m( B! j: Z& [# b
- Q. D: a- e5 D5 ~
消失的打印
$ m0 I5 e" @3 L; O( G7 J5 c0 P为了明确卡住的位置,就去修改了库的源码,添加一些打印(此时还是在旧版本uboot下编译的),结果发现卡住的位置或随着添加打印的变化而变化,且有些打印语句,添加后未打印出来。
6 _. i8 n. L3 x我决定先从这些神秘消失的打印入手。1 g6 F" p1 \/ ?! u/ o, l
分析下uboot中的printf实现,最底层就是写寄存器,是一个同步的函数,也没什么可疑的地方。
% G8 k% L/ q/ F4 u为了确认打印不出来的时候,到底有没有调用到printf,我决定给printf增加一个计数器,在gd结构体中,增加一个printf_count字段,初始化为0,每次打印时执行printf_count++并打印出值。9 r" S$ D" \3 d% d1 d8 U, ?+ s
设计这个试验,本意是确认未打印出来时是否确实也调用到了printf,但却有了别的发现,实验结果中printf_count值会异常变化,不是按打印顺序递增,而是会突变成很大的异常值。
5 E8 f1 M2 @5 @& V. J( }+ P: Z7 jprintf_count是gd结构体的成员,那就是gd的问题了。进一步将uboot全局结构体gd的地址打印出来。确认了原因是gd结构体的指针变化了。+ M+ C$ a9 b/ J  J, U: l
这也可以解释部分打印消失的现象,原因是我们在gd中有另一个字段,用于控制打印等级。当gd被改动了,printf就可能解析出错,误以为打印等级为0而提前返回。
% l- g1 g5 y" ]/ t9 S5 N8 n/ z3 Z4 e4 }. d" ?3 [

4 L/ @7 c& |$ }7 ?1 x& j+ t3 ogd的实现$ Z) Z9 {# E2 |2 q! ]
那么好端端的,gd为什么会被改了呢?这就要先看看gd到底是怎么实现的了。uboot中维护了一个全局的结构体gd。在代码中加入DECLARE_GLOBAL_DATA_PTR;/ b6 y% m) D4 J, U( T

6 D; I  b3 v3 O+ r& B6 F
即可使用gd指针访问这个全局结构体,许多地方都会借助gd来保存传递信息。进一步看看这个宏的定义
. ~+ _  r+ ~$ ^* Z0 `旧版本uboot:
8 b8 D9 i' L* M6 G+ k" t#define DECLARE_GLOBAL_DATA_PTR        register volatile gd_t *gd asm ("r8")8 }/ Y2 _% G* `
9 {/ g! |3 Z/ }+ f& [
新版本uboot:! s  r8 s- [! @) R3 r  [! f9 k- t; r
#define DECLARE_GLOBAL_DATA_PTR        register volatile gd_t *gd asm ("r9")
7 i( z( E4 e4 O" x% V* b
居然不一样,一个是将gd的值放到r8寄存器,一个是放在r9寄存器。
7 r2 m7 g+ _/ q1 B; P+ f那么就可以猜测到,库是在旧版本uboot中编译出来的,可能使用了r9,那么放到新版本uboot中去,就会破坏r9寄存器中保存的gd值,导致一系列依赖gd的代码不能正常工作。7 G+ [( n* ?0 F
" x4 C# O& {- Q- w; A
. g2 \4 p/ {, G! _: D3 o: _
验证改动
; m8 ^* [( x8 n# F: {- g" U( R为了求证,将库反汇编出来,发现确实避开了r8寄存器,但使用了r9寄存器。
# s) U8 O. G- `% ?$ b: P/ @说明uboot在指定gd寄存器的同时,还有某种方法让其他代码不使用这个寄存器。. \' \8 U  {# C$ e3 V  P) u
那是不是把旧uboot中的这个r8改成r9,重新编译库就可以了呢?试一下,还是不行。
9 @1 q1 ~0 Z1 j, J, {$ {* ]那么禁止其他代码使用r8寄存器肯定就是通过别的方式实现的了。简单粗暴地在旧版本uboot下搜索r8,去掉.c .h等类型后,很容易发现了
/ b# k/ ^0 C& }. ~' ~./arch/arm/cpu/armv7/config.mk:24LATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-floa
! d7 V4 [4 k$ J  T( q
将-ffixed-r8修改为-ffixed-r9,重新编译出库,这回就可以正常工作了,打印正常,启动正常。反汇编出来也可以看到,新编译出来的库用了r8没有用r9。' T. T* ]! u- v2 b  T$ h/ z) _  O
当然更好的改法,是直接在新版本的uboot中编译,这是最可靠的。# F8 a* ^2 m, [* o1 Y* K! P1 o7 q
$ u7 N5 i$ d' U# O9 D
) b' x- v# v* w, @8 p% t, V: Z7 @
追本溯源
* E$ N/ N/ i# ]9 D5 i* O4 P话说回来,为什么两个版本的uboot,会使用不同的寄存器呢?难道有什么坑?这就得去翻一下git记录了。
( m+ D1 z* d& I8 h) pcommit fe1378a961e508b31b1f29a2bb08ba1dac063155, Y  ^) G# Z6 j" C+ J
Author: Jeroen Hofstee <jeroen@myspectrum.nl>
& j, P# f2 l$ F2 @! p% nDate:   Sat Sep 21 14:04:41 2013 +0200. V6 {8 C- D! _* z" l
8 |- P+ S" @! }( e" _+ e3 Q
    ARM: use r9 for gd; C9 i/ P  b% a% P% ?0 e8 P; o! K
    & `. A# i0 I* |5 q
    To be more EABI compliant and as a preparation for building
/ ]/ b! y* m# }8 }. v    with clang, use the platform-specific r9 register for gd6 z2 F# R. `7 v3 \) x) E
    instead of r8.( x; @) F% T9 A; I3 w: F- V
   
) N# ^( I$ h4 V& e: N1 m    note: The FIQ is not updated since it is not used in u-boot,2 Q% Y" Y/ @* `( w: A
    and under discussion for the time being.
' `& p2 u6 ~& J8 G8 J    1 P) d: y+ {" X5 ~2 U
    The following checkpatch warning is ignored:' J6 V' z, w  l  b) R" q
    WARNING: Use of volatile is usually wrong: see
9 @: g5 R$ d7 O+ P7 _    Documentation/volatile-considered-harmful.txt
) q% Q5 c" l$ M  x3 a    5 j; U# P- m5 I6 k8 G) t
    Signed-off-by: Jeroen Hofstee <jeroen@myspectrum.nl>
" S* C. q# m5 r2 b. ~    cc: Albert ARIBAUD <albert.u.boot@aribaud.net>

1 p* S9 @5 y6 w1 R! Q/ a
1 ?4 T- P" `: m5 I
从git记录中,也可以确认完整地将r8切换到r9,都需要做哪些修改
/ V, Q* {! N6 udiff --git a/arch/arm/config.mk b/arch/arm/config.mk% a% _" u9 n4 ^
index 16c2e3d1e0..d0cf43ff41 1006440 m3 c& [8 j4 C( n. q" y
--- a/arch/arm/config.mk, x: }1 R" Z# D
+++ b/arch/arm/config.mk( s2 `% x/ u9 }0 Z* o: B1 H
@@ -17,7 +17,7 @@ endif8 ?1 r* a: T7 |9 K+ A+ x

0 ^* u# d; J3 Q' b; }# l LDFLAGS_FINAL += --gc-sections
& W; t! l- V% s" m! d PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections \+ ?* U( e9 g" i( g  m
-                     -fno-common -ffixed-r8 -msoft-float
/ z# ^/ ]8 K4 k" o: D* g9 x3 V+                     -fno-common -ffixed-r9 -msoft-float
2 R0 Y# b! @! ?1 q& J# a/ ] $ G4 ~" E# r0 G
# Support generic board on ARM
1 T- I. I# k0 \ __HAVE_ARCH_GENERIC_BOARD := y
% K# s" T% i0 J/ Odiff --git a/arch/arm/cpu/armv7/lowlevel_init.S b/arch/arm/cpu/armv7/lowlevel_init.S
8 o4 b( ]4 X4 o6 i; n$ ]+ Iindex 82b2b86520..69e3053a42 1006440 c9 o! Q7 ]6 H
--- a/arch/arm/cpu/armv7/lowlevel_init.S
( g9 p1 t( r, O7 y6 s: r+++ b/arch/arm/cpu/armv7/lowlevel_init.S; H* Z" v8 e% e+ c4 {, n
@@ -22,11 +22,11 @@ ENTRY(lowlevel_init)
% c7 {) V0 o/ d3 ^        ldr     sp, =CONFIG_SYS_INIT_SP_ADDR6 U- N5 s% G  R/ J6 R2 W9 w% J
        bic     sp, sp, #7 /* 8-byte alignment for ABI compliance */
& f0 C; H+ I- B0 \, N #ifdef CONFIG_SPL_BUILD: z! c( Z% `3 q! Q+ u
-       ldr     r8, =gdata
: {  x1 X% c7 B( I6 @2 Q  \1 e+       ldr     r9, =gdata. F% S- Q: s; \( k& o: P
#else8 B$ F% _: s+ b$ e
        sub     sp, #GD_SIZE, \) s9 k! o: \6 B
        bic     sp, sp, #7' G3 {5 f1 b$ p! W/ @
-       mov     r8, sp
, B6 K$ G3 l$ }  f% i+ S/ g% @+ Y+       mov     r9, sp+ P, y# y- |' N7 s" {
#endif2 Z2 K# c2 z; A8 W9 {5 p* N
        /*" \  G, X3 }. h1 A  K! H* e7 e2 l  F
         * Save the old lr(passed in ip) and the current lr to stack+ Q) p6 O* u7 t6 G! Y1 \' N, F
diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h
' Q$ o5 m: n! R+ M6 B% W  ~" J. gindex 79a9597419..e126436093 100644* ^. `$ y" W& M( d2 Z
--- a/arch/arm/include/asm/global_data.h
0 Z0 f8 U0 b- V2 b& S+++ b/arch/arm/include/asm/global_data.h0 @/ ^- S4 d( j% Q
@@ -47,6 +47,6 @@ struct arch_global_data {# p4 z( \8 f' k0 b0 V) Q" M9 T" R
, d: f; W( v" T3 k9 I. E4 L
#include <asm-generic/global_data.h>. g+ W- @8 G" j6 [/ M- e
9 _& M; q: e9 Z1 v
-#define DECLARE_GLOBAL_DATA_PTR     register volatile gd_t *gd asm ("r8")1 P4 I' e& Q: W! T, Y% s6 q
+#define DECLARE_GLOBAL_DATA_PTR     register volatile gd_t *gd asm ("r9")  T/ U( V/ I9 B& D; G

# E8 \  M4 S( N) u8 d% t8 i& B6 C #endif /* __ASM_GBL_DATA_H */
' i7 J5 C; f; F' q2 g+ h5 O
diff --git a/arch/arm/lib/crt0.S b/arch/arm/lib/crt0.S
' r  h1 H$ z# b9 I/ `+ |# V' Yindex 960d12e732..ac54b9359a 100644) L8 }: H+ }! q% D; ~1 [
--- a/arch/arm/lib/crt0.S* j% p3 I' F5 u& F' @. I; r2 W6 S4 S
+++ b/arch/arm/lib/crt0.S# D4 C  {& U2 |& M* u$ _
@@ -69,7 +69,7 @@ ENTRY(_main)+ t# R; @. @0 B& |
        bic     sp, sp, #7      /* 8-byte alignment for ABI compliance */9 n, ^! f' A6 H7 z3 H
        sub     sp, #GD_SIZE    /* allocate one GD above SP */
6 H9 C0 f8 m+ }; o0 q        bic     sp, sp, #7      /* 8-byte alignment for ABI compliance */
2 r; ^1 _6 _7 {7 ~0 s$ D5 l-       mov     r8, sp          /* GD is above SP */
9 B  o  C) i+ [* I9 h+       mov     r9, sp          /* GD is above SP */6 E- ~0 L" r! F$ @9 v
        mov     r0, #05 w& a/ `8 ?7 ]* _
        bl      board_init_f
7 s3 t3 d5 }; k: `3 C4 A. |: d   P! }3 c/ `. E; ~' V0 P4 {
@@ -81,15 +81,15 @@ ENTRY(_main)- V9 R" z% J# ^! N0 ]
  * 'here' but relocated.
/ `3 u$ J- y3 ^% g2 ?  */6 Y+ j' m$ s7 e4 \

5 G/ l! k7 W- }4 O+ O9 t8 [' `* P-       ldr     sp, [r8, #GD_START_ADDR_SP]     /* sp = gd->start_addr_sp */
& f' E7 G! M7 D6 r6 L+       ldr     sp, [r9, #GD_START_ADDR_SP]     /* sp = gd->start_addr_sp */
1 K6 Q# f' L% R/ y1 Q8 ~        bic     sp, sp, #7      /* 8-byte alignment for ABI compliance */
1 d8 K; t3 X9 _  U! `-       ldr     r8, [r8, #GD_BD]                /* r8 = gd->bd */
. x( D. C6 J# F, p. F% g-       sub     r8, r8, #GD_SIZE                /* new GD is below bd */" @7 E. D' z  v' s0 c/ L/ b
+       ldr     r9, [r9, #GD_BD]                /* r9 = gd->bd */- p5 {) h* P  X5 `, _
+       sub     r9, r9, #GD_SIZE                /* new GD is below bd */0 \& v+ v4 V0 _5 A7 I+ n* n

; v6 \  o* I7 Y7 D& H- P        adr     lr, here- y( {2 s# m, d# W. X
-       ldr     r0, [r8, #GD_RELOC_OFF]         /* r0 = gd->reloc_off */
0 D0 f/ G) H' ^+       ldr     r0, [r9, #GD_RELOC_OFF]         /* r0 = gd->reloc_off */& g& M; @3 T, B
        add     lr, lr, r00 ^# p7 D. C5 q) e8 J
-       ldr     r0, [r8, #GD_RELOCADDR]         /* r0 = gd->relocaddr */
1 W: [' L4 {. X! P4 x+       ldr     r0, [r9, #GD_RELOCADDR]         /* r0 = gd->relocaddr */, F# s& ?& S) c' y
        b       relocate_code; |* f* T4 l7 x! y! }& b+ X: L
here:4 g6 p1 Y: j  U. R9 W# [

/ d% S' N* Z7 B2 ]! v! t8 l@@ -111,8 +111,8 @@ clbss_l:cmp r0, r1                  /* while not at end of BSS */
9 i! x' ^& R1 F. K) u        bl red_led_on' o) G( N  j" K0 b( q+ M) v; l
. v3 k! `$ F# T. t9 k' r
        /* call board_init_r(gd_t *id, ulong dest_addr) */$ B6 @" v6 c( [# t3 ]
-       mov     r0, r8                  /* gd_t */
% V2 {* r& w5 ]1 a' U  E. A-       ldr     r1, [r8, #GD_RELOCADDR] /* dest_addr */% F) b/ F4 t- r6 @* L
+       mov     r0, r9                  /* gd_t */( ^8 o2 l+ w  l) i: T, g* f
+       ldr     r1, [r9, #GD_RELOCADDR] /* dest_addr */6 U7 A$ X. @' e- `3 G3 F
        /* call board_init_r */: a" d# @4 C* }7 {
        ldr     pc, =board_init_r       /* this is auto-relocated! */

* [7 j+ N# [( @启动慢问题  W' A6 v  b! W, O# N: v: `
问题简述7 l, u8 t, W  {! k3 M
填了几个坑之后,新的uboot可以启动到内核了,但发现启动速度非常慢,内核启动速度慢了接近10倍!明明是同一个内核,为什么差异这么大。
) I' e/ q# M# J  L  l8 V/ n2 J
/ \: \0 i6 `( L* c6 f4 o" C) j
排查寄存器* m- h! n0 E- X
初步排查了下设备树配置,以及uboot跳转内核前的一些关键寄存器,确实在两个版本的uboot中有所不同,但具体去看这些不同,发现都不会影响速度,将一些驱动对齐之后寄存器差异基本就消失了。
" F( d0 N$ e! k: B5 G! _5 j; L( \6 A# D+ O, t! ~. {* M0 o/ G

" D- y* f0 M  v$ d6 ?6 O) a- m; W差异的分界0 {5 \: B. e/ d& |9 B
那再细看,kernel的速度有差异,uboot呢?在哪个时间点之后,速度开始产生差异?& ]" t2 [7 W/ ]: c
尝试在两个版本的uboot中插入一些操作,对比时间戳,发现两个uboot在某个节点之后的速度确实有区别。
0 L) m* \' p: P7 m' ?% H进一步排查,原来是在打开cache操作之后,旧uboot的速度就会比新uboot快。尝试将旧uboot的cache关掉,则二者基本一致。尝试将旧uboot操作cache的代码,移植到新uboot,未发生改变。
! S3 r/ Z6 N/ l% o9 x% [此时可确认新uboot的开cache有问题。但觉得这个跟kernel启动慢没关系。因为uboot进入kernel之前都会关cache,由kernel自己去重新打开。
8 P2 i' l/ h1 X8 |( R也就是不管是用哪份uboot,也不管uboot中是否开了cache,对kernel阶段都应该没有影响才对。) i% x5 Y5 s: m) L6 C! ]
于是记录下来uboot的这个问题,待后续修复。先继续找kernel启动慢的原因。(注:现在看来当时的做法是有问题的,这里的异常这么明显,应该设法追踪下去找出原因才对)
' ?# n6 O. Q$ j; q  f! E* ?
9 h+ ~" H" K' @% g1 }# ]
; Z2 p6 E- m; w
锁定uboot6 q: q% B* w. C, I4 J8 A8 w. v# q
uboot的嫌疑非常大,但还不能完全确认,因为uboot之前还有一级spl。是否会是spl的问题呢?1 G$ u! s8 b) g, C6 P; |8 C% U
尝试改用新spl+旧uboot,启动速度正常。而新spl+新uboot的启动速度则很慢,其他因素都不变,说明问题确实出在uboot阶段。
" b" N7 Z' d6 J  b( O  J$ E
$ |$ d3 z7 {$ M8 c  W; g6 L6 ^$ ]" c
8 A* u0 n% Z$ j3 |
多做or少做" h; M0 N+ k2 q5 t) t. I' t- u
当时到这一步就卡住了,直接比较两份uboot的代码不太现实,差异太大了。
, D" \3 C  S/ R  O2 r6 `后来我就给自己提了个问题,到底新uboot是多做了某件事情,还是少做了某件事情?
, U) M: U' G6 K( b; f" X; {换个说法,目前已知0 p, I& @) D1 {" J( a
spl --> 旧uboot --> kernel(速度快)
- U3 p( Z9 \/ x  z/ B- Vspl --> 新uboot --> kernel(速度快)) \8 q/ q' e% F; V) K  k
但到底是以下的情况A还是情况B呢?/ ^9 L- z& M) m: M2 w' p. J6 W
A: spl(速度慢) --> 旧uboot(做了某个会提升速度的操作) --> kernel(速度快)
/ S; T4 E* }6 \' Y( e2 C   spl(速度慢) --> 新uboot(少做了某个会提升速度的操作) --> kernel(速度慢)" n7 m) e: ?1 O8 W3 d" I

2 p9 V7 {, ~3 C; u2 F+ |B: spl(速度快) --> 旧uboot(没做特殊操作) --> kernel(速度快)
$ e: Y* u1 Y% M4 @   spl(速度快) --> 新uboot(多做了某个会限制速度的操作) --> kernel(速度慢)
* N) X; j. K! O9 `4 m% Q
为了验证,我决定让spl直接启动内核,看看内核到底是快是慢。
* s4 e8 ]2 Q# k, x支持过程碰到了一些小问题) z; J/ [. y! O" O' b9 M6 i% q
1.spl没有能力加载这么大的kernel
* L9 M6 h0 h+ E2 P2 n% B解决:此时不需要kernel能完全启动,只需要能加载启动一段,足以体现出启动速度是否正常即可,于是裁剪出一个非常小kernel来辅助实验。
8 _: d9 {! J( t4 a2.kernel需要dtb
$ o# U- _5 u3 q; R8 e解决:内核有一个CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE选项。选上重新编译。编译后再用dd将kernel和dtb拼接到一起,作为新的kernel。这样,spl就只需要加载一个文件并跳转过去即可。3 Z0 T1 D/ n, b, e/ [& U
试验结果,spl启动的kernel和使用新uboot启动的kernel速度一致,均比旧uboot启动的kernel慢。说明,旧uboot中做了某个关键操作,而新uboot没做。
# }: C, t$ r7 e4 ]: w
' i- ~6 t5 _1 S7 a

6 }% `  J) Q; |. \. g' t4 p找出关键操作
) `1 U- E; R, s5 e6 k那接下来的任务就是,找出旧uboot中的这个关键操作了。1 ^0 N0 |/ i( h0 t5 v% J9 r2 ?
怎么找呢?有了上一步的成果,我们可以使用以下方法来排查
  • spl加载kernel和旧uboot

  • spl跳转到旧uboot,此时kernel其实已经在dram中准备好了,随时可以启动

  • 在旧uboot的启动流程各个阶段,尝试直接跳转到kernel,观察启动速度

  • 如果在旧uboot的A点跳转kernel启动慢,B点跳转启动快,则说明关键操作位于AB点之间。

    $ o4 L4 y8 N6 O7 f
方法有了,很快就锁定到start.S,进一步在start.S中揪出了这段代码
( h- \8 g. V7 k  T- w#if defined(CONFIG_ARM_A7)
$ w; Q6 O& P6 X6 w2 [% s@set SMP bit
1 B: G9 x3 A4 P$ q    mrc     p15, 0, r0, c1, c0, 1
: i( f0 @0 W5 ?' s2 f3 i. ]    orr        r0, r0, #(1<<6)
' o% a- \% Z4 P) |5 f8 L    mcr        p15, 0, r0, c1, c0, 19 Z, T+ j6 Y/ C* ]$ q
#endif( d$ o* g: L5 y* N+ V
新uboot的start.S中没有这段代码,尝试在新uboot的start.S中添加此操作,速度立马恢复正常了。
7 P& i8 k, M  b. e/ m" ?* \再全局搜索下,原来这个新版本uboot中,套路是在board_init中进行此项设置的,而这个平台从旧版本移植过来,就没有设置 SMP bit, 补上即可。
! k8 v! B7 g' o# l, D- G$ C* |4 K2 z& I4 q6 P
; v  m1 P) M9 l- u+ T" |
SMP bit是什么2 t* T, T6 D; o) ~
SMP 是指对称多处理器,看起来这个 bit 会影响多核的 cache一致性,此处没有再深入研究。0 x- [4 X  x7 t1 G, N3 |
但可以知道,对于单处理器的情况,也需要设置这个bit才能正常使用cache。贴下arm的图和描述: 微信图片_20200911150031.png 6 ~: g3 q+ N# }3 l9 V/ @3 r
[6] SMP
3 n! O7 K9 z  {2 b# P( z) d& W
( a/ l+ E& l& q7 ^  _# SSignals if the Cortex-A9 processor is taking part in coherency or not.( H9 R) ^* X: }0 D, i) T! @1 y
' Q% g" B) I$ d% j
In uniprocessor configurations, if this bit is set, then Inner Cacheable Shared is treated as Cacheable. The reset value is zero.
! s) @" i) g; ]0 @: _+ K; g# [1 Z6 }
搜下kernel的代码,发现也是有地方调用了的。不过这个芯片是单核的,根本就没配置CONFIG_SMP。
7 r2 S$ c, U2 L( c; i#ifdef CONFIG_SMP
$ q/ x9 z4 r6 I" Y' W. ` ALT_SMP(mrc p15, 0, r0, c1, c0, 1)
2 d7 s) L4 C7 `2 o9 @  ` ALT_UP(mov r0, #(1 << 6))  @ fake it for UP
$ P/ G3 _& g1 n0 [) C6 e tst r0, #(1 << 6)   @ SMP/nAMP mode enabled?: `, i9 F3 E* y+ Y
orreq r0, r0, #(1 << 6)  @ Enable SMP/nAMP mode- H6 a: c" E% d$ ^# U. u% i
orreq r0, r0, r10   @ Enable CPU-specific SMP bits
* R, X9 u7 Q$ E- i8 b# J7 n; X* ? mcreq p15, 0, r0, c1, c0, 1
; |0 E# Y; ?9 k$ e' }: F#endif
; k' R" a0 S  B! n6 J2 [  \
总结6 J: x4 \- Y! M9 \
整理出来一方面是记录这两个bug,另一方面也是想记录下当时的一些操作。毕竟同样的bug可能以后都不会碰到了,但解bug的方法和思路却是可以积累复用的。
1 E0 r8 u: L- T' k) m: S$ ]# [4 {( f1 b5 Z) [$ i
赞 收藏 评论0 发布时间:2020-9-11 15:02

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版