smdk2410 UBoot 汇编阶段分析

Uboot代码结构详细分析 1. Bootloader功能分析 Bootloader(如Uboot、Redboot、Blob、vivi等)直接和CPU、外围硬件设备(存储器、网卡、LCD等)打交道,负责初始化硬件设备,以及负责拉起内核:建立内存空间映射图,为内核的启动运行做好一切准备,最后将Linux内核代码加载到RAM中运行。 一般来说,bootload都会提供两种操作模式: 正常启动模式:无需开发者和用户干涉,上电后自动开始运行,完成启动内核的任务; 下载模式(开发者模式):需要用户干预,进入下载模式,使用uboot命令 阅读详情
 

首先根据链接脚本我们知道程序从u-boot-2009.03/cpu/arm920t/start.S开始,而且入口是_start,因此我们先看start.S,首先是下面的程序:

 

 40 .globl _start

 41 _start: b       start_code

 42         ldr     pc, _undefined_instruction

 43         ldr     pc, _software_interrupt

 44         ldr     pc, _prefetch_abort

 45         ldr     pc, _data_abort

 46         ldr     pc, _not_used

 47         ldr     pc, _irq

 48         ldr     pc, _fiq

 49

 50 _undefined_instruction: .word undefined_instruction

 51 _software_interrupt:    .word software_interrupt

 52 _prefetch_abort:        .word prefetch_abort

 53 _data_abort:            .word data_abort

 54 _not_used:              .word not_used

 55 _irq:                   .word irq

 56 _fiq:                   .word fiq

 

42-49行首先42行直接是一个跳转指令,跳到start_code处,43-49行将相应的变量的值装入pc中,其实也是跳转指令,这8行构成了arm架构的异常向量表,共32个字节,是各种异常处理程序的入口,请注意这是硬件决定的,不可更改,当发生了对应的异常的时候,会自动到地址为0x00-0x1c的异常向量表中查找对应的异常处理程序的地址,然后跳转去执行。这里start_code对应的是reset异常,在以前的u-boot版本都是直接用reset的,现在改成了start_code。

  Address              Exception             Mode in Entry

0x00000000             Reset                 Supervisor

0x00000004             Undefined instruction    Undefined

0x00000008             Software Interrupt       Supervisor

0x0000000C             Abort (prefetch)        Abort

0x00000010             Abort (data)            Abort

0x00000014             Reserved              Reserved

0x00000018             IRQ                  IRQ

0x0000001C             FIQ                  FIQ

还有一个问题,了解arm指令的朋友可能会对此处使用ldr有疑问,为什么不用adr了,在平常写arm汇编的时候感觉adr比ldr要好用,因为它不用管程序是如何链接的,有时候使用ldr考虑链接的问题会搞得我们焦头烂额的,但是这里可不能这样用,因为adr是不能跨越段的,即不能通过pc计算出其他段的偏移,如果异常处理程序在其他文件或段中就会出错了。

 

109 start_code:

110         /*

111          * set the cpu to SVC32 mode

112          */

113         mrs     r0,cpsr

114         bic     r0,r0,#0x1f

115         orr     r0,r0,#0xd3

116         msr     cpsr,r0

117

118         bl coloured_LED_init

119         bl red_LED_on

 

113行,将cpsr的内容读到r0中;

114行,bic位清零指令,0x1f=00011111,所以将r0的低5位清成0;

115行,让r0或上0xd3,而0xd3=11010011,即将0,1,4,6,7bit置成了1,模式位对应的0-4bit,10011即为svn模式,之后6,7位置成1表示将禁止irq和fiq。

118行,跳转到函数coloured_LED_init() (在u-boot-2009.03 /lib_arm/board.c中),执行完后返回继续执行red_LED_on(),下面的代码就是这两个函数:

 

125 void inline __coloured_LED_init (void) {}

126 void inline coloured_LED_init (void) __attribute__((weak, alias("__coloured_LED_init")));

127 void inline __red_LED_on (void) {}

128 void inline red_LED_on (void) __attribute__((weak, alias("__red_LED_on")));

 

这里很有必要提一下126行,128行,可以看到在声明这两个函数的时候后面加了__attribute__((weak, alias("xxx"))),这是gcc的扩展属性,这里有两个属性weak, alias,weak属性的作用是将这个函数声明为weak,在这种情况下使用这个函数时,如果有这个函数的定义的话就使用这个函数,如果没有这个函数的定义的话就是一个空函数。而alias的作用是别名,即括号中的xxx跟这个函数是别名,跟linux中的alias的意义是一样的。因此执行118行实际上就是执行__coloured_LED_init(),而119行执行的是__red_LED_on (),它们都是空的,也就是什么都不做。

 

接下来:

135 #if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)

136         /* turn off the watchdog */

137

138 # if defined(CONFIG_S3C2400)

139 #  define pWTCON                0x15300000

140 #  define INTMSK                0x14400008      /* Interupt-Controller base addresses */

141 #  define CLKDIVN       0x14800014      /* clock divisor register */

142 #else

143 #  define pWTCON                0x53000000

144 #  define INTMSK                0x4A000008      /* Interupt-Controller base addresses */

145 #  define INTSUBMSK     0x4A00001C

146 #  define CLKDIVN       0x4C000014      /* clock divisor register */

147 # endif

148

149         ldr     r0, =pWTCON

150         mov     r1, #0x0

151         str     r1, [r0]

152

153         /*

154          * mask all IRQs by setting all bits in the INTMR - default

155          */

156         mov     r1, #0xffffffff

157         ldr     r0, =INTMSK

158         str     r1, [r0]

159 # if defined(CONFIG_S3C2410)

160         ldr     r1, =0x3ff

161         ldr     r0, =INTSUBMSK

162         str     r1, [r0]

163 # endif

164

165         /* FCLK:HCLK:PCLK = 1:2:4 */

166         /* default FCLK is 120 MHz ! */

167         ldr     r0, =CLKDIVN

168         mov     r1, #3

169         str     r1, [r0]

170 #endif  /* CONFIG_S3C2400 || CONFIG_S3C2410 */

 

138-147行定义相关寄存器的地址,pWTCON是看门狗控制寄存器,INTMSK是中断屏蔽寄存器,INTSUBMSK是中断子屏蔽寄存器,CLKDIVN是clock divisor register,用来设置FCLK,HCLK,PCLK三者的比例。

149行,将pWTCON设置为0,即将看门狗关闭。

153-163行,首先156-158行将INTMSK的所有位置为1,即可屏蔽所有中断,159-163行,表示如果是2410的话,会有级联的中断控制器,因此还需要将子中断屏蔽寄存器的所有中断进行屏蔽。

165-170行,将CLKDIVN设置为3,即设置为FCLK:HCLK:PCLK = 1:2:4

 

176 #ifndef CONFIG_SKIP_LOWLEVEL_INIT

177         bl      cpu_init_crit

178 #endif

 

177行,如果没有定义过CONFIG_SKIP_LOWLEVEL_INIT,就跳到cpu_init_crit处。

 

236 #ifndef CONFIG_SKIP_LOWLEVEL_INIT

237 cpu_init_crit:

238         /*

239          * flush v4 I/D caches

240          */

241         mov     r0, #0

242         mcr     p15, 0, r0, c7, c7, 0   /* flush v3/v4 cache */

243         mcr     p15, 0, r0, c8, c7, 0   /* flush v4 TLB */

244

245         /*

246          * disable MMU stuff and caches

247          */

248         mrc     p15, 0, r0, c1, c0, 0

249         bic     r0, r0, #0x00002300     @ clear bits 13, 9:8 (--V- --RS)

250         bic     r0, r0, #0x00000087     @ clear bits 7, 2:0 (B--- -CAM)

251         orr     r0, r0, #0x00000002     @ set bit 2 (A) Align

252         orr     r0, r0, #0x00001000     @ set bit 12 (I) I-Cache

253         mcr     p15, 0, r0, c1, c0, 0

254

255         /*

256          * before relocating, we have to setup RAM timing

257          * because memory timing is board-dependend, you will

258          * find a lowlevel_init.S in your board directory.

259          */

260         mov     ip, lr

261 #if     defined(CONFIG_AT91RM9200EK)

262

263 #else

264         bl      lowlevel_init

265 #endif

266         mov     lr, ip

267         mov     pc, lr

268 #endif /* CONFIG_SKIP_LOWLEVEL_INIT */

 

241-243行,失效I/D cache, TLB。

248-253行,关闭mmu和cache,这里249行,将13,9,8bit清零(13—异常向量表基地址:0x0, 9—Disable System Protection, 8—Disable ROM Protection),250行,将7,2,1,0bit清零(7—为0的时候表示小端字节序,2-- Data Cache Disabled,1-- Alignment Fault checking disabled,0—为0的话MMU disabled),251行,将bit 1 设置为1表示Fault checking enabled,252行,将bit 12设置为1表示使能 I-Cache。

上面的几条指令都是协处理器指令,比较固定,看2410的datasheet就可以找到。

260行,因为下面要继续调用子程序,所以需要将之前已经保存在lr中的pc值再保存在ip中,之后261行,将pc值保存到lr中,跳转到lowlevel_init,这跟函数在u-boot-2009.03/board/samsung/smdk2410/lowlevel_init.S下:

 

129 _TEXT_BASE:

130         .word   TEXT_BASE

131

132 .globl lowlevel_init

133 lowlevel_init:

134         /* memory control configuration */

135         /* make r0 relative the current location so that it */

136         /* reads SMRDATA out of FLASH rather than memory ! */

137         ldr     r0, =SMRDATA

138         ldr     r1, _TEXT_BASE

139         sub     r0, r0, r1

140         ldr     r1, =BWSCON     /* Bus Width Status Controller */

141         add     r2, r0, #13*4

142 0:

143         ldr     r3, [r0], #4

144         str     r3, [r1], #4

145         cmp     r2, r0

146         bne     0b

147

148         /* everything is fine now */

149         mov     pc, lr

150

151         .ltorg

152 /* the literal pools origin */

153

154 SMRDATA:

155     .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))

156     .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))

157     .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))

158     .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))

159     .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))

160     .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))

161     .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))

162     .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))

163     .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))

164     .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)

165     .word 0x32

166     .word 0x30

167     .word 0x30

 

整个lowlevel_init.S文件中就只有这个函数,相关的宏定义非常的长,就不全部贴出来了,这里说说这个函数到底做了什么。因为后面我们不管是将内核copy到内存中,还是在u-boot中执行程序,都涉及到内存,flash,外设等的使用,因此在使用前必须要保证他们可用,而存储控制器就是用来控制它们的,所以我们这里就需要先对其进行初始化。这里需要先简单讨论一下存储控制器,2410平台上存储控制器共有13个寄存器,BANK0-BANK5用来接外设,flash,因此只需要设置BWSCON和BANKCONx(x为0-5),而BANK6,BANK7接SDRAM,除了设置BWSCON和BANKCONx(x为6,7),还需要设置其他四个寄存器,而这13个寄存器的地址是连续的,BWSCON是第一个寄存器,详细情况件2410的datasheet。

 

137-138行,SMRDATA为154-167行这13个寄存器(后面讨论)的值的开始地址,137行将其保存在r0中,_TEXT_BASE的值为TEXT_BASE,而TEXT_BASE = 0x33F80000在u-boot-2009.03/board/samsung/smdk2410/config.mk中进行定义,138行r1为0x33F80000。

139行,计算出SMRDATA跟TEXT_BASE之间的偏移保存到r0中,也就是在SRAM中SMRDATA数据的首地址,因为u-boot.bin之前是经过链接的,因此链接时在程序中SMRDATA数据的首地址是相对TEXT_BASE的,而现在数据在SRAM中的时候,SMRDATA数据的首地址是相对0的,因此当前SRAM中的SMRDATA数据的首地址 = SMRDATA跟TEXT_BASE之间的偏移-0 = SMRDATA跟TEXT_BASE之间的偏移。

140行将 BWSCON的寄存器的地址保存在r1中,141行r2为r0+13*4,其实就是最后一个寄存器的值的地址,即167行对应的数据的地址,它是用来控制循环的。

142-146行,循环的将SMRDATA的13个数据写入存储控制器的13个寄存器中。

149行,返回调用的函数 cpu_init_crit,这样我们又回到了start.S中,继续执行到start.S的266-267行,在返回调用 cpu_init_crit的地方继续执行180行。

 

180 #ifndef CONFIG_SKIP_RELOCATE_UBOOT

181 relocate:                               /* relocate U-Boot to RAM           */

182         adr     r0, _start              /* r0 <- current position of code   */

183         ldr     r1, _TEXT_BASE          /* test if we run from flash or RAM */

184         cmp     r0, r1                  /* don't reloc during debug         */

185         beq     stack_setup

186

187         ldr     r2, _armboot_start

188         ldr     r3, _bss_start

189         sub     r2, r3, r2              /* r2 <- size of armboot            */

190         add     r2, r0, r2              /* r2 <- source end address         */

191

192 copy_loop:

193         ldmia   r0!, {r3-r10}           /* copy from source address [r0]    */

194         stmia   r1!, {r3-r10}           /* copy to   target address [r1]    */

195         cmp     r0, r2                  /* until source end addreee [r2]    */

196         ble     copy_loop

197 #endif  /* CONFIG_SKIP_RELOCATE_UBOOT */

 

 

这段代码的作用是为了bootloader的第二阶段(即monitor)作准备的,将完整的u-boot代码copy到内存中,后面就跳到内存的代码中去执行,你如果想在u-boot中执行代码,进行调试的话,就可以用到了它,但是一般在最终的产品发布的时候一般并不需要这样的。

 

182-185行,r0是当前代码的起始地址,而r1是_TEXT_BASE,即正常情况下u-boot在内存中的起始地址,184行,比较了r0,r1就可以判断当前是否在内存中,如果相等表示已经在内存中了,就不用复制了直接跳转到stack_setup,如果不再内存中就还需要将u-boot复制到内存的_TEXT_BASE的地方。

187-197行,看过上面lowerlevel_init中copy数据的方法,这里就很好明白了,187行,将_armboot_start对应的地址传到r2里,188行将_bss_start对应的对应的地址传给r3, _armboot_start在start.S的前面定义,如下:

 77 .globl _armboot_start

 78 _armboot_start:

 79         .word _start

 

可以看到_armboot_start

就是_start,也就是程序的开始地址,而_bss_start定义在

 84 .globl _bss_start

 85 _bss_start:

 86         .word __bss_start

 

而__bss_start定义在链接脚本u-boot-2009.03/board/samsung/smdk2410/u-boot.lds中

 28 SECTIONS

 29 {

 30         . = 0x00000000;

 31

 32         . = ALIGN(4);

 33         .text      :

 34         {

 35           cpu/arm920t/start.o   (.text)

 36           *(.text)

 37         }

 38

 39         . = ALIGN(4);

 40         .rodata : { *(.rodata) }

 41

 42         . = ALIGN(4);

 43         .data : { *(.data) }

 44

 45         . = ALIGN(4);

 46         .got : { *(.got) }

 47

 48         . = .;

 49         __u_boot_cmd_start = .;

 50         .u_boot_cmd : { *(.u_boot_cmd) }

 51         __u_boot_cmd_end = .;

 52

 53         . = ALIGN(4);

 54         __bss_start = .;

 55         .bss (NOLOAD) : { *(.bss) . = ALIGN(4); }

 56         _end = .;

 57 }

 

之后189行,r2=r3-r2=__bss_start - _start=代码段的长度

190行,r2=r0+r2=_start+代码段的长度=当前代码段的结束地址

192-196行, copy u-boot的代码到内存中来

 

上面程序在不管是否需要将u-boot copy到内存中去,都会执行到下面的 stack_setup来:

 

199         /* Set up the stack                                                 */

200 stack_setup:

201         ldr     r0, _TEXT_BASE          /* upper 128 KiB: relocated uboot   */

202         sub  r0, r0, #CONFIG_SYS_MALLOC_LEN  /* malloc area                      */

203         sub     r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo                        */

204 #ifdef CONFIG_USE_IRQ

205         sub     r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)

206 #endif

207         sub     sp, r0, #12             /* leave 3 words for abort-stack    */

208

209 clear_bss:

210         ldr     r0, _bss_start          /* find start of bss segment        */

211         ldr     r1, _bss_end            /* stop here                        */

212         mov     r2, #0x00000000         /* clear                            */

213

214 clbss_l:str     r2, [r0]                /* clear loop...                    */

215         add     r0, r0, #4

216         cmp     r0, r1

217         ble     clbss_l

218

219         ldr     pc, _start_armboot

220

221 _start_armboot: .word start_armboot

 

这段代码的作用是建立堆栈,和一些必要的段,同上面,这里也是为了后面服务的,如果你不打算进入下载模式的话,不想在u-boot中执行程序,那么这段代码有没有是无所谓的,因为,内核启动之后是会重新对这些内存地址进行设置的。

201行,r0=_TEXT_BASE, 202行,r0=r0- CONFIG_SYS_MALLOC_LEN,这样之后,这是在为malloc预留空间,也就是说_TEXT_BASE下CONFIG_SYS_MALLOC_LEN长的范围是malloc使用的区域。

203行,为全局参数预留内存空间

204-206行,如果打算使用IRQ,FIQ模式,就为他们预留内存空间

207行,为abort异常预留12字节的空间,并将当前的地址赋给sp,这样就为内存栈设置好了,之后如果在u-boot中运行程序时需要使用栈的时候就从这里开始。

209-217行,清除bss段。

219行,跳转到_start_armboot,也就是函数 start_armboot,此函数存放在u-boot-2009.03/lib_arm/board.c,这样就到了u-boot的第二阶段了。

 

    进入了第二阶段,程序其实也就是进入了下载模式,这个阶段只是为了在u-boot环境下运行程序而存在的,即假如你只想在在初始化之后就启动内核的话,这个阶段没有也是没有关系的,这样的话,你就需要更改代码,将复制u-boot完整代码之后的代码全部不要,并加上将内核copy至指定地址,并建好tag list段就好了,设置好r0,r1,r2的值,跳转到内核的起始地址就可以将内核启起来了。这里第二阶段的c语言代码就不说了,很容易看懂的。

uboot 第一阶段源码分析 阅读详情

相关推荐

uboot源码分析——stage 1

我们人为的把uboot的启动分为stage1和stage2,区分的标准是以编程语言和代码的作用。 stage1主要用arm汇编及一部分C的混合编程,完成底层硬件的初始化设置; stage2则完全用C实现,在进行一些硬件(外设)初始化的同时,为linux启动提供参数和软硬件环境。 Stage1源码分析 通过分析Makefile和u-boot.lds发现,cpu/arm920t

Burning Water 1212

嵌入式Linux作业二分析u-boot-1.1.6在smdk2410开发板上的启动代码

嵌入式Linux作业二分析u-boot-1.1.6在smdk2410开发板上的启动代码

enheihei的博客 965

SMDK2410 原理图

SMDK2410评估板设计图纸

u-boot启动代码分析

u-boot版本为u-boot-2009.08,平台smdk2410 一、第一阶段启动代码分析 在学习ARM时就知道,ARM在上电复位时将PC指针修改为0,即ARM是从0地址开始读取指令执行的。在cpu/arm920t/目录下有个u-boot.lds链接脚本,首先看代码段定义: . =0x00000000; . =ALIGN(4); .text : { cp...

weixin_30835933的博客 209

SMDK2410官方代码和原理图

SMDK2410官方bootloader、usb等源码和原理图

保姆级教程:手把手教你用Jacquard V2数据集训练机器人抓取模型(附完整代码)

本文提供了一份详细的保姆级教程,手把手教你使用Jacquard V2数据集训练机器人抓取模型。从环境配置、数据准备到模型架构设计、训练优化和实际部署,全程解析并附完整代码,帮助开发者快速掌握视觉抓取技术。

weixin_29031057的博客 313

u-boot源码分析 --- 启动第二阶段 ,基于2410 启动代码 分析

我们先来看初始化函数表: init_sequencelib_arm/board.c:typedef int(init_fnc_t) (void);init_fnc_t*init_sequence[] = {    cpu_init,       /*basic cpu dependent setup */    board_init,     /*basic b

LYJ个人博客,记录技术、八卦、生活,分享各种心得,期待与朋友们一同进步 3254

BLE蓝牙胎压监测

胎压监测系统新技术

qq_41851841的博客 1252

2410启动代码分析

ADS下C语言的入口方式和ROM镜像文件的生成这部分介绍下ADS下如何生成可以运行的ROM镜像文件,我们知道当程序下载到flash中运行的时候,对于RW、ZI数据就存在着两个环境,一个load环境,一个是exec环境,有时候由于速度的需要RO数据也要重新加载,那么对RO数据也是有两个环境。编译器产生ROM镜像文件时候,这三块数据的存放依次为RO、RW、ZI,并且地址空间时连续的。但是到了运行的

albert的嵌入式专栏 1826

某知名系统漏洞挖掘与利用思路探索

本文以安全研究为目的,分享对该套系统的代码审计和漏洞挖掘过程,文中所提到的漏洞均已提交给CNVD&CITIVD,请勿用做非法用途。

C20220511的博客 1904

Arduino应用——PWM控制直流电机风扇

Arduino应用——PWM控制直流电机风扇PWM原理实验器件功能描述如何改变文本的样式插入链接与图片实现代码生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 最近在使用arduino UNO开发板完成课程小作业。其中一个要求设计一个电风扇控制系统,要求能够通过PWM调节风扇的转速。期间搜索了许多例程和方法,但受限于器件,效果不

hypecycle的博客 2万+

u-boot2013.01 smdk2410 启动第一阶段分析

u-boot2013.01 smdk2410  -->2440 启动分析 1.u-boot启动第一阶段  start.S (arch\arm\cpu\arm920t)     _start: b start_code     1.1 set the cpu to SVC32 mode    mrs r0, cpsr bic r0, r0,

Android 系统开发 1141

我的GIT练习ONE

Git 是一个分布式版本控制及源代码管理工具;Git 可以为你的项目保存若干快照,以此来对整个项目进行版本管理每一次的练习,都是对自身知识的巩固,以及对自身知识的一个测试。

是个非常热爱生活、乐观、奋斗、努力的逗比青年 8867

uboot启动源码分析

开发板smdk2410的uboot为例。 第一阶段文件为cpu/arm920t/start.S和board/smdk2410/lowlevel_init.S。 一、第一阶段 1、设置cpu为svc模式 2、关看门狗、关中断 3、cpu初始化 4、设置栈 5、时钟初始化 6、拷贝uboot到ram 7、清除bss段 8、set PreLoadedONRAM 9、执行start_armboot,进...

weixin_33785972的博客 102

22h2版本的win10安装Docker Desktop时页面空白

摘要:Windows10 22H2系统重装Docker时出现安装界面卡死问题,通过管理员CMD执行静默安装命令解决。命令指定了WSL-2后端及多个自定义数据存储路径(安装目录、Hyper-V数据、Windows容器数据、WSL数据),安装需等待几分钟。最终验证安装成功。

猿小白的博客 654

Python 爬虫实战:豆瓣电影海报批量获取(Top250 榜单 + 可视化展示)

在信息爆炸的时代,数据已成为决策的核心,而数据的获取是数据分析的第一步。本文将详细介绍如何利用 Python 爬虫获取豆瓣电影 Top250 榜单的海报,并对数据进行可视化展示,助你更好地了解电影市场的趋势和用户的喜好。

yansideyucsdn的博客 717

uboot学习——配置过程分析

一、uboot的功能分析 uboot的终极目标是将内核加载到内存上,并向内核传递传递机器ID和标记列表地址,因此,基本的功能有可以读flash,访问sdram,这是最基本的要求,此外为了有合适的时序还要初始化时钟,关看门狗,此外,为了开发方便,还需要具备网络下载,USB下载,串口调试功能,因此需要初始化网卡控制器、USB控制器、串口控制器等。这些初始化工作对于系统的正常运行至关重要,但在分析这部

小毛桃 417

Dify之八添加各种在线大模型

Dify之八添加各种在线大模型

yilvyangguang520的博客 938

移植uboot-分析uboot启动流程(详解)

本节总结: uboot启动流程如下: 1)设置CPU为管理模式 2)关看门狗 3)关中断 4)设置时钟频率 5)关mmu,初始化各个bank 6)进入board_init_f()函数(初始化定时器,GPIO,串口等,划分内存区域) 7)重定位 复制uboot,然后修改SDRAM上的uboot链接地址) 8)清bss 9)跳转到board_init_r()函数,启动流程结束 1.首先来安装arm-linux-gcc-4.3.2交叉编译器 mkdir arm-li...

一口Linux的专栏 4130

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

U-Boot 1.1.2 简单修改smdk2410.h

工作开始了,先把U-boot解压缩到你喜欢的地方。然后打开Source Navigator,选择New Project。在接下来的窗口中,选择一个你喜欢的Project File的名字,然后在Add Directory里选择你把U-Boot1.1.2解压缩到的那个目录。再选择OK。然后等等,U-Boot这个变态的东西有143MB大……接下来出现了一个窗口。(5-23 SNAV启动)这个窗口里列出了

wiserstar的专栏 994

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

uboot移植之启动过程--汇编过程start.s

uboot移植之启动过程--汇编过程start.s 说明:本文基于uboot-1.16,代码来源其中,代码版权归原作者所有。 代码版权:Copyright (C) 2001 - 2011 by Wolfgang Denk, DENX Software Engineerin

hail100的专栏 724

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

ARM汇编中的ldr和adr的区别及其在uboot中相关源码的分析

ARM汇编中的ldr和adr的区别及其在uboot中相关源码的分析

uffgfbft的博客 305

UBOOT学习总结

1. UBOOT的主要功能 UBOOT的主要任务是初始化硬件(如:串口,内存),然后将内核从Flash中读到RAM中,然后跳转到内核的入口点去运行,也就是启动操作系统。   UBOOT和BIOS的差异:PC机的引导程序由BIOS和位于硬盘MBR中的引导程序(GRUB或LILO)一起组成。BIOS在完成硬件检测和资源分配后,将硬盘中的引导程序(GRUB/LILO)读到系统内存中然后将控制权交给

luoguoxian12的博客 1007

uboot 在 ARM s3c2410 上移植过程

http://www.cublog.cn/u/20871/showart.php?id=270528总述u-boot是德国DENX小组的开发用于多种嵌入式CPU的bootloader程序,在LINUX下可以通过CVS来得到当前正在开发的u-boot软件。当前版本号:u-boot 1.0.2,见include/version.h中的定义。#cvs –dserver:anonymous@cvs.s

AwingPig 793

uboot移植之源码流程分析篇3(超详细!)

uboot移植之前期准备篇1 uboot移植之Makefile分析概述篇2 uboot移植之init_sequence_f函数数组分析(番外篇) uboot移植之修改支持SDRAM篇4 uboot移植之修改支持NorFlash篇5 uboot移植之修改支持NandFlash识别篇6(超详细) 一、添加对smdk2440的支持 1、ubuntu下,先在/board/samsung目录下...

弯弯月牙儿 2478
上一篇: QT 模仿QQ的截图
下一篇: type高级用法——分类展示
karry_vcent
博客等级 码龄15年 93粉丝 45原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值