Android training class (86) bootloader before kernel runs

Publisher:纯真年代Latest update time:2024-10-21 Source: cnblogsKeywords:Android Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

In fact, it takes a lot of hard work to load and run the kernel of the Android system, because everything is difficult at the beginning. At the beginning of a system, there are no resources to use. The CPU only recognizes the address 0x00000000 and runs the first instruction from there. And this code has a size limit and cannot be very large. Therefore, it is necessary to develop a boot program to run there. In the training course here, the S3C6410 development board is mainly used, and UBoot is used as the boot program (Bootloader). UBoot is a very common boot program, and it is widely used in embedded systems. It is also very powerful. The design architecture is very flexible and very convenient to port to different embedded devices.


As we know from the previous section, ARM CPU is fixed to start running from 0x00000000, so the compiled size of UBoot cannot be placed in the memory space of 0x00000000, so how does UBoot get control? In fact, in S3C6410, different levels can be set through the CPU pins, and you can choose to run the program inside the CPU, and then let this small program load UBoot to the appropriate address to run. So the next question is where is the appropriate address for UBoot? To understand this appropriate address, you need to read the manual of S3C6410. By reading this manual, you will find that the CPU's memory is fixed in two address spaces, as follows:

0x50000000--0x5FFFFFFF, size is 256M

0x60000000--0x6FFFFFFF, size is 256M

From this, we can see that all memory RAM must be placed in this address space, that is, the physical address space, so UBoot must be loaded into this memory space to run. So does UBoot need to know where to run when it is compiled? The answer is yes. When UBoot is running, there is a lot of data that needs to be found to address the memory address. When UBoot is compiled, the following is specified:

TEXT_BASE = 0xc7e00000

Wow, why is the address here 0xc7e00000? Is it wrong? In fact, there is a lot of stuff here. The content related to it is MMU. The so-called MMU is a memory mapping hardware. Its main function is to map the unlimited virtual memory address space to the limited physical memory address space. The function is to reuse the physical memory and facilitate the compilation of all software. From this, we can know that UBoot is compiled to run at the virtual address 0xc7e00000. Before the MMU is turned on, its physical address is 0x57e00000. In fact, it is the same place in terms of physical address.


From the previous we can know that the real physical address of UBoot is 0x57e00000, and the corresponding virtual address is 0xc7e00000. This address is a high-end address relative to 256 memory. Why is it put into this address to run, instead of the physical address of 0x50000000 (the virtual machine address 0xC0000000)? In fact, this is to prepare for the subsequent kernel Linux operation, otherwise they will fight with each other and the whole system will fail. You can see the relevant information from the memory image file compiled by UBoot:

c7e00000T _start

c7e00020t _undefined_instruction

c7e00024t _software_interrupt

c7e00028t _prefetch_abort

c7e0002ct _data_abort

c7e00030t _not_used

c7e00034t _irq

c7e00038t _fiq

c7e0003ct _pad

c7e00040T _end_vect

c7e00040t _TEXT_BASE

c7e00044t _TEXT_PHY_BASE

c7e00048T _armboot_start

c7e0004cT _bss_start

c7e00050T _bss_end

c7e00054t reset


This image file indicates that all start codes are relative to 0xc7e00000, including all data accesses. In the MMU configuration of UBoot, the following code is used to map the physical address 0x50000000 to the virtual address 0xc0000000, as follows:

//128MB for SDRAM 0xC0000000 -> 0x50000000

.set__base, 0x500

.rept0xD00 - 0xC00

FL_SECTION_ENTRY__base,3,0,1,1

.set__base,__base+1

.endr


The boot program is loaded and run, and after it is fully prepared, the kernel can be loaded and run. The kernel address is also particular. Generally, the Linux kernel needs to be loaded at the physical address 0x50008000, so the virtual address is 0xc0008000, so the kernel can be loaded and run at the low end, and the high end address can be used for all applications to run.


To summarize, the CPU starts running the Flash program from 0x00000000, then relocates UBoot to the physical address 0x57e00000 (virtual address 0xc7e00000) to run, then turns on the MMU, which corresponds to running at the virtual address 0xc7e00000, then loads the kernel to the virtual address 0xc0008000 (physical address 0x50008000), and then jumps to this address to run. Therefore, UBoot must specify the virtual address 0xc7e00000 as the base address to connect to the program.


The following is a code snippet of UBoot loading the kernel and running it:

voiddo_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],

ulong addr, ulong *len_ptr, intverify)

{

#ifdefCONFIG_CMDLINE_TAG

char *commandline = getenv("bootargs"); //Get kernel boot parameters

#endif


theKernel = (void (*)(int, int,uint))ntohl(hdr->ih_ep); //The kernel entry address specified in mkimage.c


/*

* Check if there is an initrd image

*/

if (argc >= 3){//Detect initrd temporary file system, including: magicnumber, CRC check of header and data, similar to the previous one

SHOW_BOOT_PROGRESS (9);


addr = simple_strtoul (argv[2], NULL, 16); //Get the address of initrd, the following detection process is similar to the kernel

}


if (data) {

initrd_start = data;

initrd_end = initrd_start + len;

}



//Start passing parameters to the kernel

#ifdefined (CONFIG_SETUP_MEMORY_TAGS) ||

defined (CONFIG_CMDLINE_TAG) ||

defined (CONFIG_INITRD_TAG) ||

defined (CONFIG_SERIAL_TAG) ||

defined (CONFIG_REVISION_TAG) ||

defined (CONFIG_LCD) ||

defined (CONFIG_VFD)

setup_start_tag (bd);

#ifdefCONFIG_SERIAL_TAG

setup_serial_tag (¶ms);

#endif

#ifdefCONFIG_REVISION_TAG

setup_revision_tag (¶ms);

#endif

#ifdefCONFIG_SETUP_MEMORY_TAGS

setup_memory_tags (bd);

#endif

#ifdefCONFIG_CMDLINE_TAG

setup_commandline_tag (bd, commandline);

#endif

#ifdefCONFIG_INITRD_TAG

if (initrd_start && initrd_end)

setup_initrd_tag ​​(bd, initrd_start,initrd_end);

#endif

#ifdefined (CONFIG_VFD) || defined (CONFIG_LCD)

setup_videolfb_tag ((gd_t *) gd);

#endif

setup_end_tag ​​(bd);

#endif


/* we assume that the kernel is in place */

printf ("nStarting kernel ...nn");


cleanup_before_linux (); //Settings required before starting the kernel


theKernel (0, bd->bi_arch_number, bd->bi_boot_params); //Start the kernel, and the uboot mission is now complete.

}



Keywords:Android Reference address:Android training class (86) bootloader before kernel runs

Previous article:ARM - Stack
Next article:Developing an Android driver that can count words (3)

Recommended ReadingLatest update time:2024-11-22 12:33

Surface Duo: An Android dual-screen phone that could replace your computer
      According to foreign media reports, after Microsoft began accepting pre-orders for the Surface Duo, which will be shipped on September 10, the device has officially become a reality. The Surface Duo was originally announced at the end of 2019, and it was expected to be launched in the 2020 holiday season, but no
[Mobile phone portable]
【Arduino】Some notes on using USB-ISP to burn into bootloader
Preface: Since the working range of my first 3D printer was too small and it was a Delta structure, I was too lazy to modify it, so I simply redesigned a new machine with UM2 structure. Then when I downloaded the marlin2.X firmware, the mega2560 bootloader had problems, so I had to start studying how to burn the Ardui
[Microcontroller]
【Arduino】Some notes on using USB-ISP to burn into bootloader
About the problem of external interrupt not responding after adding bootloader to stm32f030
Problem Description: I was debugging the stm32f030 chip recently. After adding the bootloader, I can jump to the application normally and the program can run normally, but it does not enter the DMA interrupt and the external interrupt cannot be responded. I have been looking for this problem for a long time... So
[Microcontroller]
The average selling price of 5G Android devices will fall below $400 in 2022
IDC has raised its near-term forecast for the worldwide smartphone market following two consecutive quarters of positive growth. IDC's Worldwide Quarterly Mobile Phone Tracker shows that smartphone shipments are expected to reach 1.38 billion units in 2021, up 7.7% from 2020. This trend is expected to continue into
[Mobile phone portable]
Microsoft confirms the establishment of the Android Experience Department, hinting at the integration of Win11 and Android
     IT Home reported on April 17 that in a new job listing, Microsoft has confirmed that it will integrate its Android work into a department called "Android Microsoft Platform and Experience". This move may allow further integration between Windows 11 and Android.   Earlier this week, Microsoft published several j
[Mobile phone portable]
The new Nokia 7.2 now has a benchmark score on the website: 6GB RAM + Android 9 system
      As early as the beginning of July, there was news that Nokia HMD was about to launch a new device codenamed Daredevil, which was later called Nokia 7.2. This device had previously been certified in Indonesia, and recently there was news that this new phone had just appeared on Geekbench, and the key specificatio
[Mobile phone portable]
The new Nokia 7.2 now has a benchmark score on the website: 6GB RAM + Android 9 system
Samsung's next-generation Galaxy Watch may abandon Tizen and adopt Android system
      According to the whistleblower Ice Universe, Samsung's next Galaxy Watch will switch from its self-developed Tizen system to Google's Android system. It is reported that Samsung will use the OneUI skin on the Android system.   According to foreign media Galaxy Club, the new smartwatch Samsung is developing is
[Mobile phone portable]
Design and Implementation of Bootloader Based on PXA272
1 Introduction The boot program in a PC is generally composed of BIOS and OS Bootloader (such as LILO or GRUB) located in MBR. However, in embedded systems, there is usually no firmware program like BIOS (some embedded CPUs have it), so the loading and startup task of the entire system is completely completed by th
[Microcontroller]
Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号