簡單整理,供日後學習。
加入gdb編譯pmon
編譯:
make cfg all tgt=rom DEBUG=-g
反彙編:
mipsel-linux-objdump -S pmon.gdb > pmon-gdb-objdump.S
初始化棧大小:16KB
_gp 在ld.script 鏈接腳本中定義 ./Targets/Bonito3a3000_7a/conf/ld.script
生成gzrom程序地址是從. = 0xffffffff8f010000 開始
start.S中
bootnow:
TTYDBG("Copy PMON to execute location...\r\n")
從彙編到C:
./genrom ../Targets/Bonito3a3000_7a/compile/Bonito/pmon > initmips.c
zloader/initmips.c
zloader/genrom
zloader/pmon.bin.c 來自於pmon.bin.gz
pmon.bin.gz 來自於pmon.bin
start.S --> initmips
首先執行的函數是initmips,tgt_machdep.c文件中
./Targets/Bonito3a3000_7a/Bonito/tgt_machdep.c
initmips
tgt_cpufreq() -------Targets/Bonito3a3000_7a/Bonito/tgt_machdep.c
_probe_frequencies()
init_legacy_rtc();
dbginit(NULL) -------pmon/common/main.c
__init();
__ctors() //初始化cmd,初始化USB相關
envinit ();
tgt_devinit();
CPU_ConfigCache();
_pci_businit(1);
_pci_hwinit (init, &def_bus_iot, &def_bus_memt); ---Targets/Bonito3a3000_7a/pci/pci_machdep.c
check_str();
init_net(1);
paraminit (); //Init system global parameters
vminit(); //Initialise "virtual memory" maps
kmeminit(); //爲kernel內存中的每頁建立數據結構(位圖)並把它們存儲在kernel內存中.同時確定kernel內存的基址,偏移量,上限等變量.
mbinit();
splhigh();
tgt_devconfig(); //顯卡相關
_pci_devinit(1);
_pci_devinit (int initialise)
_pci_setup_devices (pd, initialise);
fb_init(fbaddress, ioaddress);//ioaddress is unuseful
config_init(); //初始化4張鏈表
configure(); //整個pci初始化的核心
config_rootfound("mainbus", "mainbus")
if ((match = config_rootsearch((cfmatch_t)NULL, rootname, aux)) != NULL)
//config_rootsearch 就是傳入這個 pci 架構的根的名字,找到根這個設備。我們傳
入的參數是 NULL 和兩個“mainbus”字符串
mapply(&m, cf);
return (config_attach(ROOT, match, aux, (cfprint_t)NULL));
gmac_mac_init();
ifinit(); //interface,進行網絡接口初始化,包括watchdog計時器的執行
init_proc (); //在這裏先初始化文件系統,然後再初始化進程描述符表的狀態和符號表信息.並讓進程描述符表的第一個元素指向當前進程.寫入它的狀態SNOTKERN,名字"pmon",pid爲1,文件信息和符號表信息.
//init_net()總算執行完畢,回到 dbginit()。
histinit ();
syminit ();
defsyms();
defsym ("start", pc); //defsym()函數把這些變量註冊在一個 hash 數組中。
initial_sr |= tgt_enable (tgt_getmachtype ());
ioctl(STDIN, TCGETA, &consterm);/* Set up initial console terminal state */
tgt_memprint(); //判斷打印出 cpu 的類型
DevicesInit(); //挨個查詢已經註冊的設備,所有已知設備都在 alldevs 這個鏈表中
_DevPartOpen(dev_disk, dev_disk->device_name);
open(path, O_RDONLY | O_NONBLOCK, 0);
dev_part_read(fd, dev->part);//現在開始讀取 disk 上的分區,dev->part 傳入的目的是存放讀取出的分區表
read_primary_part_table(fd, 0, ppTable); //讀取 fd 代表的 disk 上分區表寫到 table 這個地址去