PS:要转载请注明出处,本人版权所有。

PS: 这个只是基于《我自己》的理解,

如果和你的原则及想法相冲突,请谅解,勿喷。

前置说明

  本文作为本人csdn blog的主站的备份。(BlogID=055)

  本文发布于 2018-03-09 16:54:53,现用MarkDown+图床做备份更新。blog原图已丢失,使用csdn所存的图进行更新。(BlogID=055)

环境说明

  uboot版本:2010.06

  前置资料:HISI3520DV300的某单板提供的SDK(datasheet,原理图)。

前言


  由于需求,需要对某板子的内存容量,以及Nand容量进行可能的“”软“”变更。(不修改硬件的情况下),于是需要研究此板子的启动模式以及内存映射相关的东西,并得到,变更后的设置,对整个系统有哪些影响。

  根据以上的需求,我对其Uboot启动过程进行了粗略的研究。

执行指令流程分析:


  本文中的分析流程是CPU从没电到上电,uboot从nand中加载执行的过程。

cpu上电
------------------------->
b reset @进svc,关mmu,关cache
------------------------->
bne normal_start_flow
------------------------->
bne do_clr_remap @关闭remap(remap关闭后,0x0000 0000 - 0x03ff ffff指向片内ram,实际只有4kb),打开cache
------------------------->
bl init_registers@ppl,mmu 等等
------------------------->
init_registers函数结束后,调用bx lr
跳转到relocate:标号
------------------------->
搬运异常向量表到片内ram,参考copy_exception_table:标号
------------------------->
在copy_exception_table:标号中,根据_start 和 _TEXT_BASE的值,来判断uboot需不需要搬运
------------------------->
copy_loop: 开始搬运uboot到_TEXT_BASE
------------------------->
stack_setup:建立堆栈和相关的信息内存区域
------------------------->
跳转到C部分继续执行。_start_armboot:
------------------------->

注意:若想知道根据相关寄存器的值为何是这样跳转的,请参考本系列后续文章中硬件相关的分析,或者自己在datasheet上去找相关内容.这里还是要吐槽一下:海思datasheet写的有点水,好多都一概而过,没有详细的解释或者举例分析,所以我的分析也可能是有误的,更准确内容估计只有联系官方的人员了。(但是官方可能不理我们这样的小白@!!@)

我添加注释的Start.S文件如下:

  (可能会有错,因为我没有理解到位或者其提供的datasheet介绍并不详细)

  在此目录下:u-boot-2010.06\arch\arm\cpu\hi3521a

/*
* armboot - Startup Code for OMAP3530/ARM Cortex CPU-core
*
* Copyright (c) 2004 Texas Instruments <r-woodruff2@ti.com>
*
* Copyright (c) 2001 Marius Gr枚ger <mag@sysgo.de>
* Copyright (c) 2002 Alex Z眉pke <azu@sysgo.de>
* Copyright (c) 2002 Gary Jennejohn <garyj@denx.de>
* Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com>
* Copyright (c) 2003 Kshitij <kshitij@ti.com>
* Copyright (c) 2006-2008 Syed Mohammed Khasim <x0khasim@ti.com>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/ #include <config.h>
#include <version.h> /*
*************************************************************************
*
* Jump vector table as in table 3.1 in [1]
*
*************************************************************************
*/ .globl _start
_start: b reset
ldr pc, _undefined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used
ldr pc, _irq
ldr pc, _fiq /* LDR <reg>, = <constant-expression> */ _undefined_instruction: .word undefined_instruction
_software_interrupt: .word software_interrupt
_prefetch_abort: .word prefetch_abort
_data_abort: .word data_abort
_not_used: .word not_used
_irq: .word irq
_fiq: .word fiq
_pad: .word 0x12345678 /* now 16*4=64 */
/*
.fill repeat{, size}{, value}
Repeat:重复填充的次数
Size:每次填充的字节,默认为1
Value:所填充的数据,默认为0
定义重复内存单元 */ __blank_zone_start:
.fill 1024*4,1,0
__blank_zone_end: .globl _blank_zone_start
_blank_zone_start:
.word __blank_zone_start .globl _blank_zone_end
_blank_zone_end:
.word __blank_zone_end .balignl 16,0xdeadbeef /*
后面的代码,16byte对齐,不足用0xdeadbeef来填充,此值网上大部分说就是"坏牛肉"的意思,无特定含义,估计方便记忆
*/
/*************************************************************************
*
* Startup Code (reset vector)
*
* do important init only if we don't start from memory!
* setup Memory and board specific bits prior to relocation.
* relocate armboot to ram
* setup stack
*
*************************************************************************/ _TEXT_BASE:
.word TEXT_BASE .globl _armboot_start
_armboot_start:
.word _start /*
* These are defined in the board-specific linker script.
*/
.globl _bss_start
_bss_start:
.word __bss_start .globl _bss_end
_bss_end:
.word _end #ifdef CONFIG_USE_IRQ
/* IRQ stack memory (calculated at run-time) */
.globl IRQ_STACK_START
IRQ_STACK_START:
.word 0x0badc0de /* IRQ stack memory (calculated at run-time) */
.globl FIQ_STACK_START
FIQ_STACK_START:
.word 0x0badc0de
#endif _clr_remap_fmc_entry:
.word FMC_TEXT_ADRS + do_clr_remap - TEXT_BASE /*
* the actual reset code
*/ reset:
/*
* set the cpu to SVC32 mode
*/
mrs r0, cpsr
bic r0, r0, #0x1f ////将 r0 的低 6 位清零,进入 ARM 状态(bit5)
orr r0, r0, #0xd3 ////将 r0 低八位置位 0x11010011,禁止 IRQ、FIQ,进 入 SVC 模式
/*
cpsr[4:0] = 0 0011(svc)
*/
msr cpsr,r0 /*
* Invalidate L1 I/D
*/
mov r0, #0 @ set up for MCR
mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs
mcr p15, 0, r0, c7, c5, 0 @ invalidate icache
/*
MCR ARM寄存器到协处理器寄存器的数据传送
MRC 协处理器寄存器到ARM寄存器的数据传送
*/
/*
* disable MMU stuff and caches
*/
mrc p15, 0, r0, c1, c0, 0
/* BIC 是 逻辑”与非” 指令, 实现的 Bit Clear的功能 */
bic r0, r0, #0x00002000 @ clear bits 13 (--V-)
bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM)
orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align
orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB
/*
ORR指令用于在两个操作数上进行逻辑戒运算,并把结果放置到目的寄存器中。操作数1应该是一
个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。该指令常用于设置操
作数1的某些位。 */
mcr p15, 0, r0, c1, c0, 0 /*
* read system register REG_SC_GEN2
* check if ziju flag
*/
ldr r0, =SYS_CTRL_REG_BASE
ldr r1, [r0, #REG_SC_GEN2]
/*
addr:0x12050140 ------> sp
*/
ldr r2, =0x7a696a75 /* magic for "ziju" */
cmp r1, r2
bne normal_start_flow
/*
Assume nomal start
*/
mov r1, sp /* save sp */
str r1, [r0, #REG_SC_GEN2] /* clear ziju flag */ /* init PLL/DDRC/pin mux/... */
ldr r0, _blank_zone_start
ldr r1, _TEXT_BASE
sub r0, r0, r1
ldr r1, =RAM_START_ADRS
add r0, r0, r1
mov r1, #0x0 /* flags: 0->normal 1->pm */
bl init_registers /* init PLL/DDRC/... */ /* after ziju, we need ddr traning */
#ifdef CONFIG_DDR_TRAINING_V2
ldr sp, =STACK_TRAINING
ldr r0, =REG_BASE_SCTL
bl start_ddr_training /* DDR training */
#endif ldr r0, =SYS_CTRL_REG_BASE
ldr r1, [r0, #REG_SC_GEN2]
mov sp, r1 /* restore sp */
ldr r1, [r0, #REG_SC_GEN3]
mov pc, r1 /* return to bootrom */
nop
nop
nop
nop
nop
nop
nop
nop
b . /* bug here */ normal_start_flow: @if running not boot from spi/nand/ddr ram,
@we skipping boot_type checking.
/*
0x1400_0000:SFC NAND/NOR MEMORY
地址空间
*/
mov r0, pc, lsr#24
cmp r0, #0x0
bne do_clr_remap check_boot_type:
ldr r0, =SYS_CTRL_REG_BASE
ldr r0, [r0, #REG_SYSSTAT]
mov r6, r0, lsr#4
and r6, #0x1
/*
此处可能有个错误,按照datasheet应该右移31bit才行
*/
cmp r6, #0 @ [4] = 0 FMC /* spi nor | spi nand */
ldreq pc, _clr_remap_fmc_entry @otherwise, [31]=1 means boot from bootrom, err
beq bug do_clr_remap:
/* do clear remap */
ldr r4, =SYS_CTRL_REG_BASE
ldr r0, [r4, #REG_SC_CTRL]
//REG_SC_CTRL reset_value:0x0000_0212,REG_SC_CTRL[9]=1,enable remap
@Set clear remap bit.
orr r0, #(1<<8)
str r0, [r4, #REG_SC_CTRL] /*
* Set ACTLR.SMP to 1
* This is a bug on Cortex-A7 MPCORE. see buglist of Cortex-A7
* The D-caches are disabled when ACTLR.SMP is set to 0 regardless of
* the value of the cache enable bit. so we must set SMP bit of ACTLR
* register before enable D-cache
*/
mrc p15, 0, r0, c1, c0, 1
orr r0, #(1 << 6)
mcr p15, 0, r0, c1, c0, 1 @enable I-Cache now
mrc p15, 0, r0, c1, c0, 0
orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */
mcr p15, 0, r0, c1, c0, 0
isb @Check wether I am running in dynamic mem bank
mov r0, pc, lsr#28
cmp r0, #8
bleq relocate ldr r0, _blank_zone_start
ldr r1, _TEXT_BASE
sub r0, r0, r1
adrl r1, _start
add r0, r0, r1
mov r1, #0 /* flags: 0->normal 1->pm */
bl init_registers
#ifdef CONFIG_DDR_TRAINING_V2
ldr sp, =STACK_TRAINING
ldr r0, =REG_BASE_SCTL
bl start_ddr_training /* DDR training */
#endif #ifndef CONFIG_SKIP_RELOCATE_UBOOT /*
0x0000 0000 0x03ff ffff
地址重映射时:此地址指向
启动地址空间。
地址重映射撤销后:此地址
空间指向片内RAM */
relocate:
@copy arm exception table in 0 address
adrl r0, _start
mov r1, #0
mov r2, #0x100 /* copy arm Exception table to 0 addr */
add r2, r0, r2
copy_exception_table:
ldmia r0!, {r3 - r10}
stmia r1!, {r3 - r10}
cmp r0, r2
ble copy_exception_table @ relocate U-Boot to RAM
adrl r0, _start @ r0 <- current position of code
ldr r1, _TEXT_BASE @ test if we run from flash or RAM
cmp r0, r1 @ don t reloc during debug,
//I think ifeq may means jtag-mode(arm on chip debug)
beq stack_setup ldr r2, _armboot_start
ldr r3, _bss_start
/*
Text segment
*/
sub r2, r3, r2 @ r2 <- size of armboot
add r2, r0, r2 @ r2 <- source end address copy_loop: @ copy 32 bytes at a time
ldmia r0!, {r3 - r10} @ copy from source address [r0]
stmia r1!, {r3 - r10} @ copy to target address [r1]
cmp r0, r2 @ until source end addreee [r2]
ble copy_loop
#endif /* CONFIG_SKIP_RELOCATE_UBOOT */ /* Set up the stack */
stack_setup:
ldr r0, _TEXT_BASE @ upper 128 KiB: relocated uboot
sub r0, r0, #CONFIG_SYS_MALLOC_LEN @ malloc area
sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE @ bdinfo
#ifdef CONFIG_USE_IRQ
sub r0, r0, #(CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ)
#endif
sub sp, r0, #12 @ leave 3 words for abort-stack
and sp, sp, #~7 @ 8 byte alinged for (ldr/str)d /* Clear BSS (if any). Is below tx (watch load addr - need space) */
clear_bss:
ldr r0, _bss_start @ find start of bss segment
ldr r1, _bss_end @ stop here
mov r2, #0x0 @ clear value
clbss_l:
str r2, [r0] @ clear BSS location
cmp r0, r1 @ are we at the end yet
add r0, r0, #4 @ increment clear index pointer
bne clbss_l @ keep clearing till at end ldr pc, _start_armboot @ jump to C code _start_armboot: .word start_armboot bug: nop
nop
nop
nop
nop
nop
nop
nop
b . /* bug here */ /*
*************************************************************************
*
* Interrupt handling
*
*************************************************************************
*/
@
@ IRQ stack frame.
@
#define S_FRAME_SIZE 72 #define S_OLD_R0 68
#define S_PSR 64
#define S_PC 60
#define S_LR 56
#define S_SP 52 #define S_IP 48
#define S_FP 44
#define S_R10 40
#define S_R9 36
#define S_R8 32
#define S_R7 28
#define S_R6 24
#define S_R5 20
#define S_R4 16
#define S_R3 12
#define S_R2 8
#define S_R1 4
#define S_R0 0 #define MODE_SVC 0x13
#define I_BIT 0x80 /*
* use bad_save_user_regs for abort/prefetch/undef/swi ...
* use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
*/ .macro bad_save_user_regs
sub sp, sp, #S_FRAME_SIZE @ carve out a frame on current
@ user stack
stmia sp, {r0 - r12} @ Save user registers (now in
@ svc mode) r0-r12 ldr r2, _armboot_start
sub r2, r2, #(CONFIG_SYS_MALLOC_LEN)
@ set base 2 words into abort
sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE + 8)
@ stack
ldmia r2, {r2 - r3} @ get values for "aborted" pc
@ and cpsr (into parm regs)
add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack add r5, sp, #S_SP
mov r1, lr
stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
mov r0, sp @ save current stack into r0
@ (param register)
.endm .macro irq_save_user_regs
sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} @ Calling r0-r12
add r8, sp, #S_PC @ !! R8 NEEDS to be saved !!
@ a reserved stack spot would
@ be good.
stmdb r8, {sp, lr}^ @ Calling SP, LR
str lr, [r8, #0] @ Save calling PC
mrs r6, spsr
str r6, [r8, #4] @ Save CPSR
str r0, [r8, #8] @ Save OLD_R0
mov r0, sp
.endm .macro irq_restore_user_regs
ldmia sp, {r0 - lr}^ @ Calling r0 - lr
mov r0, r0
ldr lr, [sp, #S_PC] @ Get PC
add sp, sp, #S_FRAME_SIZE
subs pc, lr, #4 @ return & move spsr_svc into
@ cpsr
.endm .macro get_bad_stack
ldr r13, _armboot_start @ setup our mode stack (enter
@ in banked mode)
@ move past malloc pool
sub r13, r13, #(CONFIG_SYS_MALLOC_LEN)
@ move to reserved a couple
sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE + 8)
@ spots for abort stack str lr, [r13] @ save caller lr in position 0
@ of saved stack
mrs lr, spsr @ get the spsr
str lr, [r13, #4] @ save spsr in position 1 of
@ saved stack mov r13, #MODE_SVC @ prepare SVC-Mode
@ msr spsr_c, r13
msr spsr, r13 @ switch modes, make sure
@ moves will execute
mov lr, pc @ capture return pc
movs pc, lr @ jump to next instruction &
@ switch modes.
.endm .macro get_bad_stack_swi
sub r13, r13, #4 @ space on current stack for
@ scratch reg.
str r0, [r13] @ save R0‘s value.
ldr r0, _armboot_start @ get data regions start
@ move past malloc pool
sub r0, r0, #(CONFIG_SYS_MALLOC_LEN)
@ move past gbl and a couple
sub r0, r0, #(CONFIG_SYS_GBL_DATA_SIZE + 8)
@ spots for abort stack
str lr, [r0] @ save caller lr in position 0
@ of saved stack
mrs r0, spsr @ get the spsr
str lr, [r0, #4] @ save spsr in position 1 of
@ saved stack
ldr r0, [r13] @ restore r0
add r13, r13, #4 @ pop stack entry
.endm .macro get_irq_stack @ setup IRQ stack
ldr sp, IRQ_STACK_START
.endm .macro get_fiq_stack @ setup FIQ stack
ldr sp, FIQ_STACK_START
.endm /*
* exception handlers
*/
.align 5
undefined_instruction:
get_bad_stack
bad_save_user_regs
bl do_undefined_instruction .align 5
software_interrupt:
get_bad_stack_swi
bad_save_user_regs
bl do_software_interrupt .align 5
prefetch_abort:
get_bad_stack
bad_save_user_regs
bl do_prefetch_abort .align 5
data_abort:
get_bad_stack
bad_save_user_regs
bl do_data_abort .align 5
not_used:
get_bad_stack
bad_save_user_regs
bl do_not_used #ifdef CONFIG_USE_IRQ .align 5
irq:
get_irq_stack
irq_save_user_regs
bl do_irq
irq_restore_user_regs .align 5
fiq:
get_fiq_stack
/* someone ought to write a more effective fiq_save_user_regs */
irq_save_user_regs
bl do_fiq
irq_restore_user_regs #else .align 5
irq:
get_bad_stack
bad_save_user_regs
bl do_irq .align 5
fiq:
get_bad_stack
bad_save_user_regs
bl do_fiq #endif /*
* v7_flush_dcache_all()
*
* Flush the whole D-cache.
*
* Corrupted registers: r0-r5, r7, r9-r11
*
* - mm - mm_struct describing address space
*/
.align 5
.global v7_flush_dcache_all
v7_flush_dcache_all:
stmfd r13!, {r0 - r5, r7, r9 - r12, r14} mov r7, r0 @ take a backup of device type
cmp r0, #0x3 @ check if the device type is
@ GP
moveq r12, #0x1 @ set up to invalide L2
smi: .word 0x01600070 @ Call SMI monitor (smieq)
cmp r7, #0x3 @ compare again in case its
@ lost
beq finished_inval @ if GP device, inval done
@ above mrc p15, 1, r0, c0, c0, 1 @ read clidr
ands r3, r0, #0x7000000 @ extract loc from clidr
mov r3, r3, lsr #23 @ left align loc bit field
beq finished_inval @ if loc is 0, then no need to
@ clean
mov r10, #0 @ start clean at cache level 0
inval_loop1:
add r2, r10, r10, lsr #1 @ work out 3x current cache
@ level
mov r1, r0, lsr r2 @ extract cache type bits from
@ clidr
and r1, r1, #7 @ mask of the bits for current
@ cache only
cmp r1, #2 @ see what cache we have at
@ this level
blt skip_inval @ skip if no cache, or just
@ i-cache
mcr p15, 2, r10, c0, c0, 0 @ select current cache level
@ in cssr
mov r2, #0 @ operand for mcr SBZ
mcr p15, 0, r2, c7, c5, 4 @ flush prefetch buffer to
@ sych the new cssr&csidr,
@ with armv7 this is 'isb',
@ but we compile with armv5
mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
and r2, r1, #7 @ extract the length of the
@ cache lines
add r2, r2, #4 @ add 4 (line length offset)
ldr r4, =0x3ff
ands r4, r4, r1, lsr #3 @ find maximum number on the
@ way size
clz r5, r4 @ find bit position of way
@ size increment
ldr r7, =0x7fff
ands r7, r7, r1, lsr #13 @ extract max number of the
@ index size
inval_loop2:
mov r9, r4 @ create working copy of max
@ way size
inval_loop3:
orr r11, r10, r9, lsl r5 @ factor way and cache number
@ into r11
orr r11, r11, r7, lsl r2 @ factor index number into r11
mcr p15, 0, r11, c7, c6, 2 @ invalidate by set/way
subs r9, r9, #1 @ decrement the way
bge inval_loop3
subs r7, r7, #1 @ decrement the index
bge inval_loop2
skip_inval:
add r10, r10, #2 @ increment cache number
cmp r3, r10
bgt inval_loop1
finished_inval:
mov r10, #0 @ swith back to cache level 0
mcr p15, 2, r10, c0, c0, 0 @ select current cache level
@ in cssr
mcr p15, 0, r10, c7, c5, 4 @ flush prefetch buffer,
@ with armv7 this is 'isb',
@ but we compile with armv5 ldmfd r13!, {r0 - r5, r7, r9 - r12, pc} #include "lowlevel_init.S"

  注意:关于Start.S我说明可能有错的地方,check_boot_type:标号附近,关于这里的详细说明,参考后续文章的内存映射部分。

后记


  无

参考文献


打赏、订阅、收藏、丢香蕉、硬币,请关注公众号(攻城狮的搬砖之路)

PS: 请尊重原创,不喜勿喷。

PS: 要转载请注明出处,本人版权所有。

PS: 有问题请留言,看到后我会第一时间回复。

HISI3520DV300 折腾记录(一)之 《Uboot-Start.S分析 以及 相关启动流程分析》的更多相关文章

  1. u-boot启动流程分析(1)_平台相关部分

    转自:http://www.wowotech.net/u-boot/boot_flow_1.html 1. 前言 本文将结合u-boot的“board—>machine—>arch—> ...

  2. u-boot启动流程分析(2)_板级(board)部分

    转自:http://www.wowotech.net/u-boot/boot_flow_2.html 目录: 1. 前言 2. Generic Board 3. _main 4. global dat ...

  3. Uboot启动流程分析(转载)

    最近一段时间一直在做uboot移植相关的工作,需要将uboot-2016-7移植到单位设计的ARMv7的处理器上.正好元旦放假三天闲来无事,有段完整的时间来整理下最近的工作成果.之前在学习uboot时 ...

  4. imx6 uboot启动流程分析

    参考http://blog.csdn.net/skyflying2012/article/details/25804209 这里以imx6平台为例,分析uboot启动流程对于任何程序,入口函数是在链接 ...

  5. Uboot启动流程分析(三)

    1.前言 在前面的文章Uboot启动流程分析(二)中,链接如下: https://www.cnblogs.com/Cqlismy/p/12002764.html 已经对_main函数的整个大体调用流程 ...

  6. Uboot启动流程分析(二)

    1.前言 在前面的文章Uboot启动流程分析(一)中,链接如下: https://www.cnblogs.com/Cqlismy/p/12000889.html 已经简单地分析了low_level_i ...

  7. Uboot启动流程分析(一)

    1.前言 Linux系统的启动需要一个bootloader程序,该bootloader程序会先初始化DDR等外设,然后将Linux内核从flash中拷贝到DDR中,最后启动Linux内核,uboot的 ...

  8. 嵌入式Linux驱动学习之路(五)u-boot启动流程分析

    这里说的u-boot启动流程,值得是从上电开机执行u-boot,到u-boot,到u-boot加载操作系统的过程.这一过程可以分为两个过程,各个阶段的功能如下. 第一阶段的功能: 硬件设备初始化. 加 ...

  9. U-BOOT启动流程分析--start.s(二)

    一.概述 u-boot的启动流程: 从文件层面上看主要流程是在两个文件中:cpu/arm920t/start.s,lib_arm/board.c, 先来分析start.s    在flash中执行的引 ...

  10. u-boot v2018.01 启动流程分析

    https://blog.csdn.net/weixin_39655765/article/details/80058644#jump1 make smdkc100_defconfig     以被默 ...

随机推荐

  1. Python中的UnboundLocalError是什么错误?如何解决?

      在一个月黑风高的夜晚,我们满心欢喜地写出以下代码: money = 10000 # 当前的财产,单位为元 def add_money(value): money += value print('当 ...

  2. Python常见设置

    pip的相关设置 设置镜像 为pip设置国内的镜像源可以提高Python库下载的速度,这里推荐使用清华大学的镜像站,使用如下命令配置: python -m pip install --upgrade ...

  3. yapi tag的问题,暂时只保留一个tag

    yapi 的tag是需要先在网页上建立好,如:

  4. Js中Number对象

    Js中Number对象 JavaScript的Number对象是经过封装从而能够处理数字值的对象,Number对象由Number()构造器以及字面量声明的值在转化为包装对象时创建,JavaScript ...

  5. Vue+SpringBoot+ElementUI实战学生管理系统-5.用户管理模块

    1.章节介绍 前一篇介绍了项目的API接口设计,这一篇编写用户管理模块,需要的朋友可以拿去自己定制.:) 2.获取源码 源码是捐赠方式获取,详细请QQ联系我 :)! 3.项目截图 列表操作 动态图 4 ...

  6. 《深入理解Java虚拟机》(六) 调优策略 -- 笔记

    目录 一.操作文档类功能,大量大对象直接进入老年代 问题现象 解决方法 通过单一Java虚拟机管理大量的内存 同一台服务器上部署若干Java虚拟机 二.异步请求大量累积 三.排查问题 排查问题: 可能 ...

  7. pinia

    Pinia学习 Vue3中 使用 官网:https://pinia.web3doc.top/introduction.html 安装 yarn add pinia # 或者使用 npm npm ins ...

  8. 配置kube-apiserver基于token的认证机制

    Kubernetes除了提供了基于CA证书的认证方式,也提供了基于HTTP Token的简单认证方式.各客户端组件与API Server之间的通信方式仍然采用HTTPS,但不采用CA数字证书.这种认证 ...

  9. vue 项目npm run dev(启动)时报错The service was stopped

    vue项目yarn upgrade后vite build报错,如何项目也运行不起来了. 报错截图: 解决办法: 删除node_modules文件夹,然后执行yarn install重新生成心的node ...

  10. 浅入Kubernetes(13):dashboard、api、访问配置

    目录 Kubectl 命令大全 安装 Kubernetes-Dashboard RESTful API 鉴权 注解 Pod YAML 结构 配置 Kubectl 命令大全 在前面,我们学习到了一些 K ...