[uboot]uboot起動kernel編(二)-bootmがkernelにジャンプする流れ
30421 ワード
一、bootm説明
bootmこのコマンドは、オペレーティングシステムイメージを起動するために使用されます.イメージファイルのベースのcpuアーキテクチャ、オペレーティングシステムのタイプ、イメージのタイプ、圧縮方法、メモリ内のイメージファイルのロードアドレス、イメージファイルの実行のエントリアドレス、イメージファイル名など、イメージファイルのヘッダから情報を取得します.次にbootmはイメージを指定したアドレスにロードし、必要に応じてイメージを解凍し、カーネルに必要なパラメータを渡し、最後にエントリアドレスにジャンプしてカーネルに入ります.ここでの説明は(http://blog.chinaunix.net/uid-20799298-id-99666.html)
開く必要があるマクロ
二、bootmの使い方
『uboot起動kernel編(一)——Legacy-uImage&FIT-uImage』では、uImageには2つのフォーマットがあることがわかりました. Legacy-uImage Legacy-uImageの場合、RAMにramdiskとfdtを別途ロードする必要があります.実行するコマンドは次の です. FIT-uImage FIT-uImageでは、kernelミラー、ramdiskミラー、fdtがFIT-uImageのミラーにパッケージされています.実行するコマンドは次の です.
三、bootm実行プロセス
まず、「[uboot](第6章)ubootプロセス--コマンドラインモードおよびコマンド処理の紹介」を参照することをお勧めします.対応U_BOOT_CMD bootmコマンドに対応するU_を見つけましたBOOT_CMDは、cmd/bootm.c do_bootmパラメータ説明「[uboot](第6章)ubootプロセス-コマンドラインモードおよびコマンド処理紹介」によりbootmコマンドを実行するとdo_bootmは呼び出されます.パラメータは次のとおりです. do_bootm実装do_bootmは以下のように実現される:
だからbootmのコアはdo_bootm_states、グローバル変数bootm_headers_t imagesをdo_としてbootm_statesのパラメータ.この関数について詳しく説明します.
四、do_bootm_statesソフトウェアプロセス
1、データ構造説明 bootm_headers_t bootm_headers_tはbootmがkernelを起動するいくつかの情報を表す構造体であり、os/initrd/fdt imagesの情報が含まれている.bootmは、パラメータとパラメータが指すミラーに基づいて、この構造問題のメンバーを埋めます.最終的には、この構造体の中の情報を使用してkernel起動情報を埋め込み、kernelにジャンプします.ubootでグローバルなbootm_を使用しましたheaders_t images.
2、状態説明 BOOTM_STATE_START #define BOOTM_STATE_START(0 x 000000000001)はbootmのいくつかの準備動作を開始する. BOOTM_STATE_FINDOS #define BOOTM_STATE_FINDOS(0 x 000000002)オペレーティングシステムミラーの検索 BOOTM_STATE_FINDOTHER #define BOOTM_STATE_FINDOTHER(0 x 0000004)は、FDTramdiskなどのオペレーティングシステムのミラー以外のミラーを検索します. BOOTM_STATE_LOADOS #define BOOTM_STATE_LOADOS(0 x 0000008)オペレーティングシステム をロード BOOTM_STATE_RAMDISK #define BOOTM_STATE_RAM DISK(0 x 0000010)操作ramdisk BOOTM_STATE_FDT #define BOOTM_STATE_FDT(0 x 0000020)動作FDT BOOTM_STATE_OS_CMDLINE #define BOOTM_STATE_OS_CMDLINE(0 x 0000040)操作commandline BOOTM_STATE_OS_BD_T #define BOOTM_STATE_OS_BD_T (0x00000080) BOOTM_STATE_OS_PREP #define BOOTM_STATE_OS_PREP(0 x 0000 0100)オペレーティングシステムにジャンプする前の準備動作 BOOTM_STATE_OS_FAKE_GO #define BOOTM_STATE_OS_FAKE_GO(0 x 0000200)/*‘Almost’run the OS*/擬似ジャンプは、一般的にkernelに直接ジャンプして に行くことができます. BOOTM_STATE_OS_GO #define BOOTM_STATE_OS_GO(0 x 0000 0400)kernelにジャンプして へ
3、ソフトウェアプロセスの説明
do_bootm_statesはstatesに基づいて実行する操作を判断する.主な流れは以下のように簡単に説明される. bootmの準備動作BOOTM_STATE_START kernel情報BOOTM_を取得STATE_FINDOS ramdiskとfdtの情報BOOTM_を取得STATE_FINDOTHER kernelを対応する位置にロード(この位置にある可能性があります)BOOTM_STATE_LOADOS リダイレクトramdiskとfdt(必ずしも必要としない)BOOTM_STATE_RAMDISK、BOOTM_STATE_FDT ジャンプ実行前の準備動作BOOTM_STATE_OS_PREP 起動パラメータを設定し、kernelがあるアドレスのBOOTM_にジャンプSTATE_OS_GO
これらのプロセスでは、bootm_が伝達されます.headers_t imagesというデータ構造は、ミラーを解析し、この構造体にデータを書く流れがあります.ジャンプするときは、この構造体の中のデータを使う必要があります.ソフトウェアコードは以下のcommon/bootm.c
主に次のような順序でいくつかの関数を使用して実現されます. bootm_start bootm_find_os bootm_find_other bootm_load_os bootm_os_get_boot_func boot_fn(BOOTM_STATE_OS_PREP, argc, argv, images); boot_selected_os boot_selected_os(argc, argv, BOOTM_STATE_OS_GO,images, boot_fn);
4、bootm_start & bootm_find_os & bootm_find_other
主に環境変数、パラメータ、uImageを解析してbootm_を埋めますheaders_t imagesというデータ構造.最終的な目的はbootm_を実現することですheaders_t imagesのメンバー: bootm_startはverifyとlmb を実現する bootm_find_osはosとepを実現する.つまり、Legacy-uImageでもFIT-uImageでも、最終的に解析されるのはこの2人のメンバーです.『uboot起動kernel編(三)——uImageを解析するkernelミラー』で具体的に説明します. bootm_find_other実装rd_start, rd_end,ft_addrとinitrd_end. つまり、Legacy-uImageでもFIT-uImageでも、最終的に解析されるのはこの2人のメンバーです.『uboot起動kernel編(四)——uImageを解析するfdt』と『uboot起動kernel編(五)——uImageを解析するramdisk』で具体的に説明します.
5、bootm_load_os
簡単に説明するとbootm_load_osでは、kernelミラーが対応する位置にloadされ、kernelミラーがmkimageで圧縮されている場合は、解凍してからloadが行われます.(ここで注意したいのは、ここの圧縮とImageをzImageに圧縮するのは同じではなく、ubootがImageまたはzImageをベースにした圧縮です!!)
その結果、上記の手順の後、kernelミラーは対応する位置にloadされます.
6、bootm_os_get_boot_func
bootm_os_get_boot_funcは、対応するオペレーティングシステムの起動関数を取得するためにboot_に格納されるfnで.次のようになります.
最終的にlinuxを起動するコア関数はdo_であることがわかります.bootm_linux. 他のいくつかの関数も最終的にboot_に呼び出されますfn、linuxに対応するdo_bootm_linuxなので、ここでは説明しません.次にdo_について説明しますbootm_linuxのプロセス
五、do_bootm_linux
arch/arm/lib/bootm.c
boot_prep_linuxは、linuxにジャンプする前の準備動作を実現するために使用されます.そしてboot_jump_linuxはlinuxにジャンプするために使用されます.グローバル変数bootm_headers_t imagesはパラメータであり、前のステップで得られたkernelミラー、ramdisk、fdtの情報を直接取得することができる. boot_prep_linuxはまずLMBの概念を説明します.LMBとはlogical memory blocksのことで、主にメモリの保持領域を表すために用いられ、主にfdtの領域、ramdiskの領域などがある.boot_prep_linuxの主な目的はLMBを修正し、LMBをfdtに記入することです.実現は以下の通りである:
ここではimageを深く勉強していません.setup_linuxは、後続に必要があればさらに深く進みます. boot_jump_linuxはarmを例にとる:arch/arm/lib/bootm.c
ここまで、kernel_を通ってentryはその後kernel環境に移行しました.興味があればkernelの起動プロセスを見てみましょう.
======================================================================================================================================================================第1段階の——proc infoの取得[kernel起動フロー](第4章)第1段階の——dtbの検証[kernel起動フロー](第5章)第1段階の——一時カーネルページテーブルの作成[kernel起動フロー](第6章)第1段階の——MMU[kernel起動フロー](第7章)第1段階の——start_にジャンプkernel
bootmこのコマンドは、オペレーティングシステムイメージを起動するために使用されます.イメージファイルのベースのcpuアーキテクチャ、オペレーティングシステムのタイプ、イメージのタイプ、圧縮方法、メモリ内のイメージファイルのロードアドレス、イメージファイルの実行のエントリアドレス、イメージファイル名など、イメージファイルのヘッダから情報を取得します.次にbootmはイメージを指定したアドレスにロードし、必要に応じてイメージを解凍し、カーネルに必要なパラメータを渡し、最後にエントリアドレスにジャンプしてカーネルに入ります.ここでの説明は(http://blog.chinaunix.net/uid-20799298-id-99666.html)
開く必要があるマクロ
CONFIG_BOOTM_LINUX=y
CONFIG_CMD_BOOTM=y
二、bootmの使い方
『uboot起動kernel編(一)——Legacy-uImage&FIT-uImage』では、uImageには2つのフォーマットがあることがわかりました.
Legacy-uImage 0x20008000,ramdisk 0x21000000,fdt 0x22000000
(1) kernel
bootm 0x20008000
(2) kernel ramdisk
bootm 0x20008000 0x21000000
(3) kernel fdt
bootm 0x20008000 - 0x22000000
(4) kernel、ramdisk、fdt
bootm 0x20008000 0x21000000 0x22000000
FIT-uImage 0x30000000, kernel :
bootm 0x30000000
三、bootm実行プロセス
まず、「[uboot](第6章)ubootプロセス--コマンドラインモードおよびコマンド処理の紹介」を参照することをお勧めします.
U_BOOT_CMD(
bootm, CONFIG_SYS_MAXARGS, 1, do_bootm,
"boot application image from memory", bootm_help_text
);
‘bootm 0x20008000 0x21000000 0x22000000’
int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
cmdtp: bootm , _u_boot_list_2_cmd_2_bootm
argc=4
argv[0]="bootm", argv[1]=0x20008000, arv[2]=0x21000000, argv[3]=0x22000000
/*******************************************************************/
/* bootm - boot application image from image in memory */
/*******************************************************************/
int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
/* determine if we have a sub command */
argc--; argv++;
if (argc > 0) {
char *endp;
simple_strtoul(argv[0], &endp, 16);
/* endp pointing to NULL means that argv[0] was just a
* valid number, pass it along to the normal bootm processing
*
* If endp is ':' or '#' assume a FIT identifier so pass
* along for normal processing.
*
* Right now we assume the first arg should never be '-'
*/
if ((*endp != 0) && (*endp != ':') && (*endp != '#'))
return do_bootm_subcommand(cmdtp, flag, argc, argv);
}
// ,
// , bootm ,
// 'bootm 0x20008000 0x21000000 0x22000000'
// argc=3, argv[0]=0x20008000 , argv[1]=0x21000000, argv[2]=0x22000000
// ‘bootm 0x30000000’
// argc=1, argv[0]=0x30000000
return do_bootm_states(cmdtp, flag, argc, argv, BOOTM_STATE_START |
BOOTM_STATE_FINDOS | BOOTM_STATE_FINDOTHER |
BOOTM_STATE_LOADOS |
BOOTM_STATE_OS_PREP | BOOTM_STATE_OS_FAKE_GO |
BOOTM_STATE_OS_GO, &images, 1);
// do_bootm_states, do_bootm_states states :
// BOOTM_STATE_START
// BOOTM_STATE_FINDOS
// BOOTM_STATE_FINDOTHER
// BOOTM_STATE_LOADOS
// BOOTM_STATE_OS_PREP
// BOOTM_STATE_OS_FAKE_GO
// BOOTM_STATE_OS_GO
}
だからbootmのコアはdo_bootm_states、グローバル変数bootm_headers_t imagesをdo_としてbootm_statesのパラメータ.この関数について詳しく説明します.
四、do_bootm_statesソフトウェアプロセス
1、データ構造説明
typedef struct bootm_headers {
/*
* Legacy os image header, if it is a multi component image
* then boot_get_ramdisk() and get_fdt() will attempt to get
* data from second and third component accordingly.
*/
image_header_t *legacy_hdr_os; /* image header pointer */ // Legacy-uImage
image_header_t legacy_hdr_os_copy; /* header copy */ // Legacy-uImage
ulong legacy_hdr_valid; // Legacy-uImage
#if IMAGE_ENABLE_FIT
const char *fit_uname_cfg; /* configuration node unit name */ //
void *fit_hdr_os; /* os FIT image header */ // FIT-uImage kernel
const char *fit_uname_os; /* os subimage node unit name */ // FIT-uImage kernel
int fit_noffset_os; /* os subimage node offset */ // FIT-uImage kernel
void *fit_hdr_rd; /* init ramdisk FIT image header */ // FIT-uImage ramdisk
const char *fit_uname_rd; /* init ramdisk subimage node unit name */ // FIT-uImage ramdisk
int fit_noffset_rd; /* init ramdisk subimage node offset */ // FIT-uImage ramdisk
void *fit_hdr_fdt; /* FDT blob FIT image header */ // FIT-uImage FDT
const char *fit_uname_fdt; /* FDT blob subimage node unit name */ // FIT-uImage FDT
int fit_noffset_fdt;/* FDT blob subimage node offset */ // FIT-uImage FDT
#endif
image_info_t os; /* os image info */ //
ulong ep; /* entry point of OS */ //
ulong rd_start, rd_end;/* ramdisk start/end */ // ramdisk
char *ft_addr; /* flat dev tree address */ // fdt
ulong ft_len; /* length of flat device tree */ // fdt
ulong initrd_start; //
ulong initrd_end; //
ulong cmdline_start; //
ulong cmdline_end; //
bd_t *kbd; //
int verify; /* getenv("verify")[0] != 'n' */ //
int state; // , bootm , 2.
#ifdef CONFIG_LMB
struct lmb lmb; /* for memory mgmt */
#endif
} bootm_headers_t;
2、状態説明
3、ソフトウェアプロセスの説明
do_bootm_statesはstatesに基づいて実行する操作を判断する.
これらのプロセスでは、bootm_が伝達されます.headers_t imagesというデータ構造は、ミラーを解析し、この構造体にデータを書く流れがあります.ジャンプするときは、この構造体の中のデータを使う必要があります.
int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
int states, bootm_headers_t *images, int boot_progress)
{
boot_os_fn *boot_fn;
ulong iflag = 0;
int ret = 0, need_boot_fn;
images->state |= states;
// states bootm_headers_t images
/*
* Work through the states and see how far we get. We stop on
* any error.
*/
// states BOOTM_STATE_START , bootm , bootm_start
if (states & BOOTM_STATE_START)
ret = bootm_start(cmdtp, flag, argc, argv);
// states BOOTM_STATE_FINDOS , kernel , bootm_find_os
if (!ret && (states & BOOTM_STATE_FINDOS))
ret = bootm_find_os(cmdtp, flag, argc, argv);
· // states BOOTM_STATE_FINDOTHER , ramdisk fdt , bootm_find_other
if (!ret && (states & BOOTM_STATE_FINDOTHER)) {
ret = bootm_find_other(cmdtp, flag, argc, argv);
argc = 0; /* consume the args */
}
/* , uImage bootm_headers_t images */
/* uImage */
/* bootm_headers_t images */
/* Load the OS */
// states BOOTM_STATE_LOADOS , , bootm_load_os
if (!ret && (states & BOOTM_STATE_LOADOS)) {
ulong load_end;
iflag = bootm_disable_interrupts();
ret = bootm_load_os(images, &load_end, 0);
if (ret == 0)
lmb_reserve(&images->lmb, images->os.load,
(load_end - images->os.load));
else if (ret && ret != BOOTM_ERR_OVERLAP)
goto err;
else if (ret == BOOTM_ERR_OVERLAP)
ret = 0;
#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY)
if (images->os.os == IH_OS_LINUX)
fixup_silent_linux();
#endif
}
// ramdinsk,do_bootm
/* Relocate the ramdisk */
#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
if (!ret && (states & BOOTM_STATE_RAMDISK)) {
ulong rd_len = images->rd_end - images->rd_start;
ret = boot_ramdisk_high(&images->lmb, images->rd_start,
rd_len, &images->initrd_start, &images->initrd_end);
if (!ret) {
setenv_hex("initrd_start", images->initrd_start);
setenv_hex("initrd_end", images->initrd_end);
}
}
#endif
// fdt,do_bootm
#if IMAGE_ENABLE_OF_LIBFDT && defined(CONFIG_LMB)
if (!ret && (states & BOOTM_STATE_FDT)) {
boot_fdt_add_mem_rsv_regions(&images->lmb, images->ft_addr);
ret = boot_relocate_fdt(&images->lmb, &images->ft_addr,
&images->ft_len);
}
#endif
/* From now on, we need the OS boot function */
if (ret)
return ret;
// , boot_fn
boot_fn = bootm_os_get_boot_func(images->os.os);
need_boot_fn = states & (BOOTM_STATE_OS_CMDLINE |
BOOTM_STATE_OS_BD_T | BOOTM_STATE_OS_PREP |
BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO);
if (boot_fn == NULL && need_boot_fn) {
if (iflag)
enable_interrupts();
printf("ERROR: booting os '%s' (%d) is not supported
",
genimg_get_os_name(images->os.os), images->os.os);
bootstage_error(BOOTSTAGE_ID_CHECK_BOOT_OS);
return 1;
}
/* Call various other states that are not generally used */
if (!ret && (states & BOOTM_STATE_OS_CMDLINE))
ret = boot_fn(BOOTM_STATE_OS_CMDLINE, argc, argv, images);
if (!ret && (states & BOOTM_STATE_OS_BD_T))
ret = boot_fn(BOOTM_STATE_OS_BD_T, argc, argv, images);
// , , BOOTM_STATE_OS_PREP
if (!ret && (states & BOOTM_STATE_OS_PREP))
ret = boot_fn(BOOTM_STATE_OS_PREP, argc, argv, images);
/* Check for unsupported subcommand. */
if (ret) {
puts("subcommand not supported
");
return ret;
}
// BOOTM_STATE_OS_GO , ,
/* Now run the OS! We hope this doesn't return */
if (!ret && (states & BOOTM_STATE_OS_GO))
ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_GO,
images, boot_fn);
/* Deal with any fallout */
err:
if (iflag)
enable_interrupts();
if (ret == BOOTM_ERR_UNIMPLEMENTED)
bootstage_error(BOOTSTAGE_ID_DECOMP_UNIMPL);
else if (ret == BOOTM_ERR_RESET)
do_reset(cmdtp, flag, argc, argv);
return ret;
}
主に次のような順序でいくつかの関数を使用して実現されます.
4、bootm_start & bootm_find_os & bootm_find_other
主に環境変数、パラメータ、uImageを解析してbootm_を埋めますheaders_t imagesというデータ構造.最終的な目的はbootm_を実現することですheaders_t imagesのメンバー:
typedef struct bootm_headers {
image_info_t os; /* os image info */
ulong ep; /* entry point of OS */
ulong rd_start, rd_end;/* ramdisk start/end */
char *ft_addr; /* flat dev tree address */
ulong ft_len; /* length of flat device tree */
ulong initrd_start;
ulong initrd_end;
ulong cmdline_start;
ulong cmdline_end;
bd_t *kbd;
int verify; /* getenv("verify")[0] != 'n' */
#ifdef CONFIG_LMB
struct lmb lmb; /* for memory mgmt */
#endif
}
5、bootm_load_os
簡単に説明するとbootm_load_osでは、kernelミラーが対応する位置にloadされ、kernelミラーがmkimageで圧縮されている場合は、解凍してからloadが行われます.(ここで注意したいのは、ここの圧縮とImageをzImageに圧縮するのは同じではなく、ubootがImageまたはzImageをベースにした圧縮です!!)
static int bootm_load_os(bootm_headers_t *images, unsigned long *load_end,
int boot_progress)
{
image_info_t os = images->os;
ulong load = os.load; // kernel
ulong blob_start = os.start;
ulong blob_end = os.end;
ulong image_start = os.image_start; // kernel
ulong image_len = os.image_len; // kernel
bool no_overlap;
void *load_buf, *image_buf;
int err;
load_buf = map_sysmem(load, 0);
image_buf = map_sysmem(os.image_start, image_len);
// bootm_decomp_image, image_buf , load load_buf
err = bootm_decomp_image(os.comp, load, os.image_start, os.type,
load_buf, image_buf, image_len,
CONFIG_SYS_BOOTM_LEN, load_end);
その結果、上記の手順の後、kernelミラーは対応する位置にloadされます.
6、bootm_os_get_boot_func
bootm_os_get_boot_funcは、対応するオペレーティングシステムの起動関数を取得するためにboot_に格納されるfnで.次のようになります.
int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
int states, bootm_headers_t *images, int boot_progress)
{
...
boot_fn = bootm_os_get_boot_func(images->os.os);
...
}
boot_os_fn *bootm_os_get_boot_func(int os)
{
return boot_os[os];
//
}
static boot_os_fn *boot_os[] = {
...
#ifdef CONFIG_BOOTM_LINUX
[IH_OS_LINUX] = do_bootm_linux,
#endif
}
最終的にlinuxを起動するコア関数はdo_であることがわかります.bootm_linux. 他のいくつかの関数も最終的にboot_に呼び出されますfn、linuxに対応するdo_bootm_linuxなので、ここでは説明しません.次にdo_について説明しますbootm_linuxのプロセス
五、do_bootm_linux
arch/arm/lib/bootm.c
int do_bootm_linux(int flag, int argc, char * const argv[],
bootm_headers_t *images)
{
/* No need for those on ARM */
if (flag & BOOTM_STATE_OS_BD_T || flag & BOOTM_STATE_OS_CMDLINE)
return -1;
// flag BOOTM_STATE_OS_PREP, boot_prep_linux
if (flag & BOOTM_STATE_OS_PREP) {
boot_prep_linux(images);
return 0;
}
// flag BOOTM_STATE_OS_GO ,
if (flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)) {
boot_jump_linux(images, flag);
return 0;
}
boot_prep_linux(images); // bootm_headers_t images boot_prep_linux
boot_jump_linux(images, flag);// bootm_headers_t images boot_jump_linux
return 0;
}
boot_prep_linuxは、linuxにジャンプする前の準備動作を実現するために使用されます.そしてboot_jump_linuxはlinuxにジャンプするために使用されます.グローバル変数bootm_headers_t imagesはパラメータであり、前のステップで得られたkernelミラー、ramdisk、fdtの情報を直接取得することができる.
static void boot_prep_linux(bootm_headers_t *images)
{
char *commandline = getenv("bootargs");
if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) {
#ifdef CONFIG_OF_LIBFDT
debug("using: FDT
");
if (image_setup_linux(images)) {
printf("FDT creation failed! hanging...");
hang();
}
#endif
}
ここではimageを深く勉強していません.setup_linuxは、後続に必要があればさらに深く進みます.
static void boot_jump_linux(bootm_headers_t *images, int flag)
{
unsigned long machid = gd->bd->bi_arch_number; // bd machine-id,machine-id uboot
char *s;
void (*kernel_entry)(int zero, int arch, uint params); // kernel , kernel , kernel _start 。
unsigned long r2;
int fake = (flag & BOOTM_STATE_OS_FAKE_GO); // , kernel
kernel_entry = (void (*)(int, int, uint))images->ep;
// kernel_entry images ep(kernel ), kernel_entry kernel
//
debug("## Transferring control to Linux (at address %08lx)" \
"...
", (ulong) kernel_entry);
bootstage_mark(BOOTSTAGE_ID_RUN_OS);
announce_and_cleanup(fake);
// images->ft_addr(fdt ) r2
if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len)
r2 = (unsigned long)images->ft_addr;
else
r2 = gd->bd->bi_boot_params;
if (!fake) {
kernel_entry(0, machid, r2);
// kernel_entry, images->ep , kernel , kernel _start 。
// 0 r0 , machid r1 , images->ft_addr(fdt ) r2
// kernel
}
}
ここまで、kernel_を通ってentryはその後kernel環境に移行しました.興味があればkernelの起動プロセスを見てみましょう.
======================================================================================================================================================================第1段階の——proc infoの取得[kernel起動フロー](第4章)第1段階の——dtbの検証[kernel起動フロー](第5章)第1段階の——一時カーネルページテーブルの作成[kernel起動フロー](第6章)第1段階の——MMU[kernel起動フロー](第7章)第1段階の——start_にジャンプkernel