Uboot is divided into two phases during system startup and kernel loading,
The first stage is mainly to write assembly code. I did not study it carefully. I just looked at the transplanted uboot code for tekkman of mini2440.
The second stage is written as C, which is easy to study and learn. Master the basic process.
(1) first-stage Functions
Hardware Device Initialization
Load the second-stage U-boot code to the ram Space
Set the stack
Step 2: Jump to the code entry
(2) Functions of the Second Stage
Initialize the hardware devices used in this phase
Check System memory ing
Read the kernel from flash to ram
Set startup parameters for the kernel
Call the kernel
The C Exit function of the second stage is:
The following code is available at the final stage of CPU/ARM920T/start. S:
Ldr pc, _ start_armboot
_ Start_armboot :. word start_armboot PC pointer will jump to lib_arm/board. the start_armboot () function defined in C (). so start_armboot (). function is the entry code of C code. The analysis starts from here.
The start_armboot () function has an endless loop,
/* Main_loop () can return to retry autoboot, if so just run it again .*/
For (;;)
{
Main_loop (); receives the command entered by the user in the uboot command line.
}
When uboot is started, if the user does not input it before # define config_bootdelay 1 times out, uboot automatically loads the Linux kernel,
During loading, the variables "bootcmd" and "bootargs" are used to start the code using the variable values defined in the uboot code.
The values of the variables "bootcmd" and "bootargs" can be modified in the uboot command line before the Linux kernel is loaded.
The values of these two parameters are as follows:
Bootcmd = NFS 0x30008000 192.168.1.149:/opt/friendlyarm/uimage; bootm ------ note that the bootm command is added at the end of the bootcmd variable.
Bootargs = noinitrd root =/dev/nfs proto = TCP, nolock, nfsvers = 3, RW nfsroot = 192.168.1.149:/mini2440/rootfs IP = 192.168.1.144: 192.168.1.149: 255.255.255.0 console = ttysac0, 115200 init =/linuxrc mem = 64 m
First, let's take a look at the two simple and clear methods to start the kernel,Boot, bootdCommand implementation.
The actual code is as follows:
/*************************************** ****************************/
/* Bootd-boot default image */
/*************************************** ****************************/
# If defined (config_cmd_bootd)
Int do_bootd (pai_tbl_t * cmdtp, int flag, int argc, char * argv [])
{
Int RCODE = 0;
# Ifndef config_sys_hush_parser
If (run_command (getenv ("bootcmd"), flag) <0)
RCODE = 1;
# Else
If (parse_string_outer (getenv ("bootcmd "),
Flag_parse_semicolon | flag_exit_from_loop )! = 0)
RCODE = 1;
# Endif
Return RCODE;
}
U_boot_cmd (
Boot, 1, 1, do_bootd,
"Boot default, I. e., run 'bootcmd '",
""
);
/* Keep old command name "bootd" for backward compatibility */
U_boot_cmd (
Bootd, 1, 1, do_bootd,
"Boot default, I. e., run 'bootcmd '",
""
);
# Endif
From the preceding command boot and bootd command implementation, the final execution of the command is the value defined by the "bootcmd" command line parameter.
That is, "NFS 0x30008000 192.168.1.149:/opt/friendlyarm/uimage; bootm ":
In the above function main_loop (), the following code snippets are provided:
S = getenv ("bootcmd ");
Debug ("### main_loop: bootcmd = \" % s \ "\ n", s? S: "<undefined> ");
If (bootdelay> = 0 & S &&!Abortboot (bootdelay ))
{
# Ifdef config_autoboot_keyed
Int Prev = disable_ctrlc (1);/* disable control C checking */
# Endif
# Ifndef config_sys_hush_parser
Run_command (S, 0 );
# Else
Parse_string_outer (S, flag_parse_semicolon |
Flag_exit_from_loop );
# Endif
# Ifdef config_autoboot_keyed
Disable_ctrlc (prev);/* restore control C checking */
# Endif
}
# Ifdef config_menukey
If (menukey = config_menukey ){
S = getenv ("menucmd ");
If (s ){
# Ifndef config_sys_hush_parser
Run_command (S, 0 );
# Else
Parse_string_outer (S, flag_parse_semicolon |
Flag_exit_from_loop );
# Endif
}
}
# Endif/* config_menukey */
# Endif/* config_bootdelay */
In the code above, the function abortboot (bootdelay ))
If the command times out during execution, the command defined by "bootcmd" is automatically executed.
Now let's take a look at how the command "bootm" command is implemented?
"Boot application image from memory", this sentence is very important, indicating that bootm execution must ensure that the uimage is included,
In "bootm ADDR", when ADDR is omitted, bootm loads the kernel image at # define config_sys_load_addr 0x30008000/* default load address.
The implementation function of the "bootm" command is do_bootm (), and the Linux kernel is loaded and started in do_bootm.
Its loading function is: The do_bootm_linux () function obtains the value of the "bootargs" environment variable. This value is finally passed to the Linux kernel for loading the file system.
The Analysis of do_bootm () and do_bootm_linux () functions can be found by other friends.
Summary
Each Command in uboot corresponds to a function implemented by it. During Linux kernel startup, it mainly executes the environment variables bootcmd and bootargs defined commands. Therefore, the definition of these two variables is very important. If the definition is incorrect, the kernel and file system cannot be correctly loaded. In particular, make sure that the partition where the file system is located.