skyeye的初始化

2021-04-13 11:03:29 字數 3442 閱讀 6456

今天早早地回到了住處,早上起來感覺到脖子很不舒服,白天在實驗室裡扭動一下都不容易,得好好善待自己,身體是革命的本錢啊!

看了一下以前的blog,本來很早就想寫關於ipv6的總結,可是過去都快乙個月了,現在都提不起興致,看來幹什麼都得趁熱打鐵,學習也是,不及時總結好多

心得,經驗都白白丟失了,將來想撿起來又得費一番功夫。不知道什麼時候把這個好習慣給丟了  :(

這段時間因為產品開始聯調,所以接觸到了單板,bootloader等東西,雖然以前有過相關的學習,但是進入真正的環境還是第一次。所以剛開始好多東西不清

楚,好在經過兩個星期的學習,也算是漸漸弄清楚了一些東西。

嵌入式系統開發是時下很熱的話題,在各個領域的應用極為廣泛,所以有很多人都想望著上面發展。另一方面因為其設計到很多底層的軟硬體只是,更是能吸

引一部分底層技術愛好者的興趣。可是對於很多人來說,嵌入式開發板需要的一筆投入讓其望而卻步。正是在這種背景下,skyeye--天目應運而生。關於

含義。它的原始碼裡面用到了大量的函式指標給跟蹤帶來了很大的麻煩。在main函式中解析完輸入引數後,呼叫init函式,主要的初始化流程可以解釋如下:

1)init: 如果是第一次呼叫init,那麼初始化device--->初始化所有以支援的裝置:net,lcd,flash等,將其放入到全域性二維指標global_mod_set中;初始化

arch--->初始化所有支援的架構,目前包括arm,bfin,mips,clodfire,ppc,將每種架構對應的arch_config_t 放入到全域性陣列skyeye_archs中;

2)讀取config檔案,並一步步解析裡面的選項,這裡用到了乙個重要的變數skyeye_option_t skyeye_options;它的每一項表示對於某種選項,應該用那個函式

進行解析。下面是一些常用的解析過程:

a)arch:一般來說這是首先被解析確定的,有些選項依賴於它。從arch_config_t skyeye_archs中,找到於配置相等的arch(arm,ppc,mips等),賦給

skyeye_config.arch;

b)cpu:如果已經解析了arch,那麼呼叫此arch的cpu解析函式,初始化全域性結構cpu_config_t *p_arm_cpu;如果還沒有初始化arch,則預設arch為arm。以

arm的cpu解析為例,他在全域性結構arm_cpus中找與配置選項一致的cpu name,並用*p_arm_cpu指向匹配的項;

c)mach:此選項指定特定的開發板,是整個skyeye執行的中心配置結構。與cpu的解析類似,都是呼叫arch的mach解析函式(每種arch對應若干種cpu,針對每

種cpu有可能有若干種開發板,所以,arch是根本)。同樣,也是在乙個全域性陣列machine_config_t arm_machines中,找mach name與配置中一致的項,並賦值

給skyeye_config.mach。

d)mem:類似,呼叫以初始化好的arch的mem解析函式。以arm為例,主要工作是初始化mem_config_t arm_mem結構體。

typedef struct

mem_config_t;

核心結構是mem_banks-->記錄了讀寫資料的方法,此mem_bank對應的起始位址,檔名,型別(ram,rom,flash)。解析函式的工作就是初始

arm_mem.mem_banks,依據選項中的map,type,file等引數,初始各mem_banks的成員。如果有file選項,則將指定的檔名拷貝到mem_banks中的相應char陣列

中(僅僅是拷貝檔名,真正的裝入檔案將在arm_reset_state-->armul_reset-->mem_reset 函式呼叫中進行);如果有boot=yes,則將

skyeye_config.start_address = mb[num].addr--->此mem_bank的起始位址。

其他的選項的解析思路應該與此類似,只是每種選項的特性不同,需要初始化的設定的變數不一樣而已。比如net,在linux平台下,需要特定的裝置檔案存

在,所以要求你裝載某個net驅動模組,以在/dev下面生成指定的裝置檔案。

現在的版本的skyeye與internal文件的描述有些出入,但實現思路應該還是不變的。核心的結構還是skyeye_option_t 。與裝置有關的是

machine_config_t.struct device_desc **devices;可以把它看作是指向了一張表,裡面的每一項都是指向此machine的某個裝置的指標。結構體struct

device_desc 是描述具體的裝置。裡面有大量的函式指標,用於讀取位元組,字等,進行i/o操作的函式。這些函式指標大致可以分為兩類(這是我自己歸納的,

不一定正確。參考原始碼中的 set_device等函式):io/mem/init類,此裝置特有的操作函式。裝置描述結構體中還有乙個指向其所屬的裝置型別的指標,以獲得

一些此型別裝置共有的操作函式。

因為對bootloader比較感興趣,所以特別關注了一下程式執行的起始位址,以下是確定方法。

相關的變數有三個 static unsigned long load_addr = 0x0;

static unsigned long load_addr_mask = 0xffffffff;

uint32_t             skyeye_config.start_address;

1)通過-e引數輸入elf檔名,-l引數輸入load_addr ,load_addr_mask。沒有-l引數的話,elf將被裝載到它的入口處,也就是elf檔案裡的指定的位址;

否則裝載到-l指定的位址。通過 tea_load_exec

2)通過記憶體選項的boot,可以指定 skyeye_config.start_address。在tea_load_exec 中,如果skyeye_config.start_address為零,那麼將會被置為elf

檔案的入口。

3)在main函式中,init後,如果輸入了elf檔案,則呼叫tea_load_exec (exec_file, 0),載入elf檔案,設定skyeye_config.start_address。並把pc指標

設定為(skyeye_config.start_address & load_addr_mask)|load_addr --->  相當於是在skyeye_config.start_address的基礎上偏移 load_addr ???有時間

可以試驗一下

所以,指定程式執行的起始位址有一下幾種方法:

1) 在elf檔案中,通過鏈結器等指定程式的入口,不用-l引數,boot選項。那麼從elf的entry開始執行

2) 使用-l引數,指定load_addr,和load_addr_mask ,那麼從load_addr開始執行

3) 在mem設定中,指定boot=yes,那麼起始執行位址為(skyeye_config.start_address & load_addr_mask)|load_addr。如果沒有elf檔案,則起始位址就是此

mem_bank的起始位址。如果有elf檔案,又有-l選項,那麼依據上式確定起始位址。 

初始化 指定初始化

id alloc 物件的誕生過程,主要是從作業系統獲得一塊足夠大的記憶體,以存放該類的全部例項變數,並將其指定為存放記憶體物件的實力變數的位置。alloc方法同時將這塊記憶體全部設定為0。結果是 bool變數初始化為no,所有的int型別變數為0,float變數為0.0,所有的指標為nil.obje...

初始化 1 預設初始化 列表初始化

初始化的基本概念 事實 初始化和賦值是兩個完全不同的操作。初始化,是建立變數時賦予其乙個初始值。賦值,是把物件的當前值擦除,用乙個新值代替。列表初始化 p39 作為c 11新標準的一部分,用花括號 來初始化變數得到了全面應用。出於某些原因,這種初始化的方式叫做列表初始化。現在,無論是初始化物件還是某...

初始化 MyBatis初始化之載入初始化

在mybatis初始化過程中,大致會有以下幾個步驟 1.建立configuration全域性配置物件,會往typealiasregistry別名註冊中心新增mybatis需要用到的相關類,並設定預設的語言驅動類為xmllanguagedriver 3.構建defaultsqlsessionfacto...