02.uboot分析之源碼第一階段

      網友投稿 794 2025-04-09

      之前寫的硬件相關的裸機源碼的流程和uboot差不多。之前的實驗主要完成以下操作:


      (1)初始化:關看門狗,初始化時鐘,初始化sdram。

      (2)程序很大時,把程序從nandflash拷貝到sdaram。

      (3)調用C函數必須設置棧sp

      .globl _start /*跳轉到reset*/ _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 _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 .balignl 16,0xdeadbeef reset: /* * set the cpu to SVC32 mode 管理模式 */ mrs r0,cpsr bic r0,r0,#0x1f orr r0,r0,#0xd3 msr cpsr,r0 /* turn off the watchdog 關看門狗*/ #if defined(CONFIG_S3C2400) # define pWTCON 0x15300000 # define INTMSK 0x14400008 /* Interupt-Controller base addresses */ # define CLKDIVN 0x14800014 /* clock divisor register */ #elif defined(CONFIG_S3C2410) # define pWTCON 0x53000000 # define INTMOD 0X4A000004 # define INTMSK 0x4A000008 /* Interupt-Controller base addresses */ # define INTSUBMSK 0x4A00001C # define CLKDIVN 0x4C000014 /* clock divisor register */ #endif #if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) ldr r0, =pWTCON mov r1, #0x0 str r1, [r0] /* * mask all IRQs by setting all bits in the INTMR - default 關中斷 */ mov r1, #0xffffffff ldr r0, =INTMSK str r1, [r0] # if defined(CONFIG_S3C2410) ldr r1, =0x3ff ldr r0, =INTSUBMSK str r1, [r0] # endif /* * we do sys-critical inits only at reboot, * not when booting from ram! * CPU初始化 */ #ifndef CONFIG_SKIP_LOWLEVEL_INIT /*讀地址指令 如果是上電后運行,代碼是從nandflash自動拷貝到sdram,則r0為0.如果是通過下載器下載到sdram,則r0為他的鏈接地址0x33f8000*/ adr r0, _start /* r0 <- current position of code */ ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ /*不相等則證明sdram還沒有被初始化。*/ cmp r0, r1 /* don't reloc during debug */ blne cpu_init_crit #endif #ifndef CONFIG_SKIP_LOWLEVEL_INIT cpu_init_crit: /* * flush v4 I/D caches 關flash */ mov r0, #0 mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ /* * disable MMU stuff and caches 清mmu */ mrc p15, 0, r0, c1, c0, 0 bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM) orr r0, r0, #0x00000002 @ set bit 2 (A) Align orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache mcr p15, 0, r0, c1, c0, 0 /* * before relocating, we have to setup RAM timing * because memory timing is board-dependend, you will * find a lowlevel_init.S in your board directory. */ mov ip, lr /*初始化存儲控制器,初始化之后內存才可以使用*/ bl lowlevel_init mov lr, ip mov pc, lr #endif /* CONFIG_SKIP_LOWLEVEL_INIT */ /* Set up the stack 設置棧 */ /*棧會一直減下去,指向不同的位置*/ stack_setup: ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot r0=0x33f80000 */ sub r0, r0, #CFG_MALLOC_LEN /* malloc area r0 =r0-CFG_MALLOC_LEN */ sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo r0 =r0-CFG_GBL_DATA_SIZE */ #ifdef CONFIG_USE_IRQ /*r0=r0-(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)*/ sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) #endif sub sp, r0, #12 /* leave 3 words for abort-stack r0=r0-12 */ #ifndef CONFIG_SKIP_LOWLEVEL_INIT /*調用初始化時鐘的C函數*/ bl clock_init #endif /*把代碼從flash讀到sdram鏈接地址*/ relocate: /* relocate U-Boot to RAM */ adr 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 */ beq clear_bss ldr r2, _armboot_start ldr r3, _bss_start sub r2, r3, r2 /* r2 <- size of armboot */ /*清楚BSS段,初始化為0的靜態變量或者全局變量*/ clear_bss: ldr r0, _bss_start /* find start of bss segment */ ldr r1, _bss_end /* stop here */ mov r2, #0x00000000 /* clear */ ldr pc, _start_armboot /*調用c函數start_armboot*/ _start_armboot: .word start_armboot

      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

      02.uboot分析之源碼第一階段

      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

      小結:設置管理模式,關看門狗,屏蔽中斷,sdram的初始化,設置棧,設置時鐘,代碼重定位,清除bss段(之前的都稱為uboot的第一階段),調用C函數start_armboot(第二階段開始)。

      BSS段清零的原因是因為這個段是BSS

      要說為什么要有BSS的話,歷史就比較久遠了。 BSS段我所知道的起源是Unix最初的時候(當然,不排除可能有更早的情況)。變量分兩種:局部變量、全局變量。

      根據C語法的規定,局部變量不設置初始值的時候,其初始值是不確定的,局部變量(不含靜態局部變量)的存儲位置位于棧上,具體位置不固定。

      全局變量(和靜態局部變量)有專門數據段存儲,初始值是0,具體位置是固定的。

      其實說到底,就兩種,一種是位置固定(數據段里),一種是位置不固定的(棧上)。

      要知道,早期的計算機存儲設備是很貴的,而很多時候,數據段里的全局變量都是0(或者沒有初始值),那么存儲這么多的0到目標文件里其實是沒有必要的。所以為了節約空間,在生成目標文件的時候,就把沒有初始值(實際就是0)的數據段里的變量都放到BSS段里,這樣目標文件就不需要那么大的體積里(節約磁盤空間)。只有當目標文件被載入的時候,加載器負責把BSS段清零(一個循環就可以搞定)。 之后,這個規則慢慢的成為一個標準配置,大多數編譯器也就都支持了BSS段。

      然后解釋幾個問題: Q:為什么局部變量初始值不是0? A:局部變量初始值也可以是零(在某些語言中就是),但這實際上需要消耗硬件指令去完成,有些時候這種清零的動作意義不大,對于編譯器來說也是一種負擔,每次調用函數都要消耗指令去清零,負擔太大。要知道全局變量在內存中只有一份,局部變量(非靜態)可以是多份的,前者一次清零就可以了,后者多次清零,負擔太大。

      Q:如果BSS不清零可不可以? A:可以,如果編譯器規定BSS段不清零,也是可以的,但這樣的話C語言語法就要改了:未初始化的全局變量和靜態局部變量,其值是未知的。甚至其它語言也要跟著改語法。

      所以,BSS段清零的原因是因為這個段是BSS 現在存儲介質這么便宜了,是不是BSS已經沒有必要了?當然不是了,介質便宜僅限于PC和數碼產品這一塊,嵌入式行業永遠都不存在存儲介質沒有限制的情況。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:Excel動態圖表―定義名稱
      下一篇:Excel2016表格怎么以副本方式打開文件
      相關文章
      五月天网站亚洲小说| 国产性爱在线观看亚洲黄色一级片| 亚洲不卡av不卡一区二区| 亚洲成av人片一区二区三区| 亚洲成在人线aⅴ免费毛片| 亚洲综合av一区二区三区| 激情五月亚洲色图| 亚洲人精品亚洲人成在线| 亚洲一级毛片视频| 亚洲精品天堂在线观看| 亚洲熟女乱色一区二区三区| 亚洲欧美国产欧美色欲| 亚洲成av人无码亚洲成av人| 亚洲AV无码专区在线观看成人| 亚洲AV无码一区二区三区电影 | 337p日本欧洲亚洲大胆裸体艺术 | 国产成人亚洲综合无码| 久久久亚洲精品蜜桃臀 | 亚洲色无码专区一区| 亚洲色成人四虎在线观看| 亚洲爆乳AAA无码专区| 久久亚洲精品11p| 亚洲精品无码久久久| 国产亚洲?V无码?V男人的天堂| 国产精品亚洲A∨天堂不卡 | 麻豆亚洲AV永久无码精品久久| 亚洲综合色一区二区三区小说| 亚洲国产福利精品一区二区| 亚洲91精品麻豆国产系列在线| 99久久婷婷国产综合亚洲| 亚洲欧美不卡高清在线| 午夜亚洲国产成人不卡在线 | 亚洲乱码无限2021芒果| 亚洲熟妇少妇任你躁在线观看| 亚洲av日韩综合一区久热| avtt亚洲天堂| 亚洲理论电影在线观看| 亚洲一区二区中文| 亚洲中文字幕一二三四区苍井空| 亚洲精品国产摄像头| 亚洲国产成人久久综合碰|