Write the bootloader yourself ------ write the second stage

Our bootloader needs to achieve the following functions,

  • Initialize hardware: turn off watchdog, set clock, set SDRAM, initialize nand falsh,
  • If the bootloader is large, relocate it to SDRAM.
  • Read kernel from nandflash to SDRAM
  • Set "parameters to pass to the kernel"
  • jump to kernel

In the first stage, we implemented initialization and relocation, and encapsulated the nandread function. Next, we will implement the next three functions. We will create a new boot.c and implement these three functions in the main function inside.

1 Read the kernel into memory from nandflash

So which address do we start reading from, where do we read, and how big is the reading? Let's use the mtd command on the uboot command line of the development board to see and get

 We can see that 0x0060000 exists in the kernal. Another problem is that the kernel we programmed is uImage, uImage=64 bytes of header + zImage. Our uImage exists at 0x0060000 here, then our zImage exists at 0x0060000 + 64 here.

So where did you read it, let's start it with the boot command in uboot, and get

 It can be seen that the kernel is placed in 30008000 of the memory, so we use the following code to read the kernel from nandflash to SDRAM.

nand_read(0x60000+64, (unsigned char *)0x30008000, 0x200000);

2 Set parameters

Our uboot needs to tell the kernel how much memory we have, and tell the kernel the command line parameters to start. These parameters are passed through tags, that is, these parameters are saved in a certain piece of memory, and then the kernel directly reads the parameters from this memory. , we need a total of four tags

	/* 2. 设置参数 */
	puts("Set boot params\n\r");
	setup_start_tag();
	setup_memory_tags();
	setup_commandline_tag("noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0");
	setup_end_tag();
  • setup_start_tag() indicates where the setup parameters start,
  • setup_memory_tags() How big is our memory for the high-speed kernel;
  • setup_commandline_tag("noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0"); command line parameter tag
  • setup_end_tag(); indicates where the parameters end.

2.1 setup_start_tag()

Let's first look at how the start_tag of uboot is written,

 There is a parameter param, let's take a look at the definition of param

 Then we also define such a structure in our bootloader, and the tag is such a structure

 The tag structure is declared in the setup.h of uboot. We directly copy the setup.h and use it, and then the u32 u16 u8 in the setup.h is not defined, let's define it inside.

Then we start to write setup_start_tag, we directly copy the setup_start_tag function in uboot,

void setup_start_tag(void)
{
	params = (struct tag *)0x30000100;

	params->hdr.tag = ATAG_CORE;
	params->hdr.size = tag_size (tag_core);

	params->u.core.flags = 0;
	params->u.core.pagesize = 0;
	params->u.core.rootdev = 0;

	params = tag_next (params);
}

After setup_start_tag get

Where params = tag_next (params); means to point to the next tag, this macro definition is the current tag+size that points to the next tag. ​​​​​

 2.2 setup_memory_tag

We also imitate the writing in uboot, let's take a look at the writing in uboot first

 Our memory starting address is 0x30000000 and the size is 64M, so we get

void setup_memory_tags(void)
{
	params->hdr.tag = ATAG_MEM;
	params->hdr.size = tag_size (tag_mem32);
	
	params->u.mem.start = 0x30000000;
	params->u.mem.size  = 64*1024*1024;
	
	params = tag_next (params);
}

2.3 setup_commandline_tag

The video is 24 minutes long.

3 jump

We refer to the code of uboot, the uboot startup mainly executes the bootm command

So we go to the uboot code to search for the bootm command, the do_bootm function in the cmd_bootm.c file, the do_bootm_linux function is called in the do_bootm function, and a function pointer is defined in it,

We also follow the definition of a function pointer,

void (*theKernel)(int zero, int arch, unsigned int params);

Guess you like

Origin blog.csdn.net/u013171226/article/details/123607387