bootloader and RO, RW, ZI in ARMC language

Publisher:AngelicHeartLatest update time:2016-07-25 Source: eefocusKeywords:bootloader  ARM Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
Bootloader is the first piece of software code that runs after the system is powered on. Simply put, they are all bootloaders, and the tasks they perform are similar.

Friends who are familiar with the x86 architecture must know that the bootloader on the x86 platform is composed of BIOS and OS Bootloader (such as Lilo and Grub) located in the hard disk MBR. After the BIOS completes the hardware detection and resource allocation, it reads the bootloader in the hard disk MBR into the system RAM. After that, the bootloader will start to take the lead, move the kernel to the memory and perform some necessary initialization work, and then jump to the kernel entry address to execute, so that the kernel starts to start, that is, the system starts.
Here we have to insert a topic. Through the above introduction, careful friends will have a question: Why do we need a bootloader? Since the bootloader only initializes the hardware and boots the kernel, why not just add this code to the kernel and start the kernel directly to complete all the work? In fact, it is completely possible to integrate the bootloader with the kernel, but if so, the kernel will lose its versatility and flexibility, and separating the bootloader from the kernel will be more conducive to development and management. The code related to the platform hardware in the startup process can be combined into the bootloader, and the kernel can focus on processing those platform-common parts (of course, there is not such a strict division in reality, there will still be some platform-related code in the kernel, but it is already relatively common).
===
...           
          ​
        ​          

    ​The following uses Image file to refer to it. Image file contains RO and RW data. The reason why Image file does not contain ZI data is that ZI data is all 0, so it is not necessary to include it. Just clear the area where ZI data is located before the program runs. Including it will waste storage space.
    Q: Why must Image contain RO and RW?         
    A: Because the instructions and constants in RO and the variables initialized in RW cannot be "created out of nothing" like ZI.   
  In fact, the instructions in ROM should at least have the following functions:
            1. Move RW from ROM to RAM, because RW is a variable and variables cannot exist in ROM.
            2. Clear all RAM areas where ZI is located to zero, because the ZI area is not in the Image, so the program needs to clear the corresponding RAM area according to the ZI address and size given by the compiler. ZI is also a variable, and similarly: variables cannot exist in ROM. In the initial stage of program running, the C program can access variables normally only after the instructions in RO complete these two tasks. Otherwise, only code without variables can be run.
    Below I will give a few examples to most intuitively explain what RO, RW, and ZI mean in C.
        1; RO
        Look at the following two programs. There is a statement between them, which is to declare a character constant. Therefore, according to what we said before, there should only be a one-byte difference in RO data (character constants are 1 byte).        
Prog1:
            #include 
            void main(void)
            {
                ;
            }
           
Prog2:
            #include 
            const char a = 5;
            void main(void)
            {           
                ;
            }
 The compiled information of Prog1 is as follows:          
======================================================================================          
Code RO Data RW Data ZI Data Debug
            948 60 0 96 0 Grand Totals         
=======================================================================================================        
Total RO Size(Code + RO Data) 1008 ( 0.98kB)
Total RW Size(RW Data + ZI Data) 96 ( 0.09kB)
Total ROM Size(Code + RO Data + RW Data) 1008 ( 0.98kB)          
============================================================================================           
The information after Prog2 compiles is as follows:          
====================================================================================================         
Code RO Data RW Data ZI Data Debug
            948 61 0 96 0 Grand Totals           
================================================================================          
Total RO Size(Code + RO Data) 1009 (0.99kB)
Total RW Size(RW Data + ZI Data) 96 (0.09kB)
Total ROM Size(Code + RO Data + RW Data) 1009 (0.99kB)           
================================================================================         
From the information after the above two programs are compiled, it can be seen that:
   The RO of Prog1 and Prog2 contains two types of data: Code and RO Data. The only difference between them is that the RO Data of Prog2 has 1 byte more than that of Prog1. This is consistent with the previous speculation. If an instruction is added instead of a constant, the result should be a difference in the size of the Code data.
     2; RWLooking
     at the two programs again, the only difference between them is an "initialized variable". According to what was said before, the initialized variable should be counted in RW, so the size of RW should be different between the two programs.     
    Prog3:
            #include 
            void main(void)
            {
                ;
            }           
    Prog4:
            #include 
            char a = 5;
            void main(void)
            {         
                ;
            }
            The information compiled by Prog3 is as follows:           
======================================================================================          
Code RO Data RW Data ZI Data Debug
            948 60 0 96 0 Grand Totals         
==============================================================================================================           
Total RO Size(Code + RO Data) 1008 ( 0.98kB) 
Total RW Size(RW             0 Grand Totals 1 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024           1024          1024        1024       1024  1024
1024            ================================================================================           Total RO Size(Code + RO Data) 1008 (0.98kB)  Total RW Size(RW Data + ZI Data) 97 (0.09kB) Total ROM Size(Code + RO Data + RW Data) 1009 (0.99kB)             ===        ... ​           ​             ​ 














            void main(void)
            {
            ;
            }        
Prog4:
            #include 
            char a;
            void main(void)
            {      
                ;
            }
The information compiled by Prog3 is as follows:        
=====================================================================================          
Code RO Data RW Data ZI Data Debug
948 60 0 96 0 Grand Totals           
============================================================================================================           
Total RO Size(Code + RO Data) 1008 ( 0.98kB)
Total RW Size(RW Data +             0 Grand Totals 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0         
0           0
0         0          0
0          ================================================================================           Total RO Size(Code + RO Data) 1008 (0.98kB) Total RW Size(RW Data + ZI Data) 97 (0.09kB) Total ROM Size(Code + RO Data + RW Data) 1008 (0.98kB)            ===            ... ​           ​     ​             ​             ​ RAM mainly refers to: PSRAM, SDRAM, SRAM, DDRAM (5) Image$$??$$Limit means = 0x0c100000 + Tatal RO size + 1                    = 0x0c200000 + 0x37 (multiples of 4, 0 to 55, a total of 56 units)

















 


Vivi is a Linux bootloader developed by Mizi for S3C241x/S3C244x. After Friendly Arm transplanted the USB download function, it became the current Supervivi. U-boot is a bootloader widely used on ARM platforms. It also supports S3C241x/S3C244x and can be used to start Linux. Eboot is a bootloader under WinCE platform. Uboot is a bootloader that downloads OS image files through USB; Eboot is a bootloader that downloads OS image files through Ethernet.

The embedded platform is different from x86, but very similar. Because of the characteristics of different platform architectures, the bootloaders for each platform do different things. Compared with the x86 platform, there is generally no bios (but these are not absolute, some platforms also have built-in boot programs similar to bios). The boot loading of the entire system is completed by the bootloader stored in a specific location of flash, rom and other storage devices. For example, in the 2410 and 2440 of the arm platform, the bootloader exists at 0x0 in the flash. After the board is powered on, the system will automatically load the first 4k code of the bootloader into the SRAM through hardware logic, and then start execution from 0 in the SRAM. In this 4k program, the basic hardware initialization will be completed, the complete bootloader will be moved to the memory, and the bootloader in the ram will be jumped to continue execution.

    Back to what we said before, after the bootloader is started, there are usually two operating modes:

The boot loading mode is that once the power is turned on, the bootloader will start the kernel immediately after performing relevant initialization. The key point is that there is no user participation in the whole process. This is actually the default processing of the bootloader. Generally, when the product design is ok and the final release is made, it will be in this state.

Everyone must be very familiar with the download module mode, which is the environment in which we are developing. We often use tftp, erase, cp.b and other commands to burn related bin and img files to the board. In this case, it is actually in the execution environment of the bootloader. So in a certain sense, most bootloaders are actually embedded operating systems, but their functions are not strong, not as complex as the structure of Linux, and they do not support multi-process and multi-threaded processing.

Bootloader types and classifications

The classification here is actually based on the operating mode of the bootloader above. According to whether a system supports the download mode above, we divide the bootloader into bootloader and monitor (this is not my classification, it is quoted from someone else's article, but I think what he said makes sense). Here, "bootloader" refers to the firmware that only boots the device and executes the main program, while "monitor" refers to the firmware that not only has the bootloader function, but can also enter the download mode.

 (1) Composition of ARM program

The "ARM program" mentioned here refers to the program being executed in the ARM system, not the bin image file saved in ROM. Please pay attention to the difference.

        ZI is an uninitialized variable in the program; ZI is zero;

(3) ARM program execution process         

From the above two points, we can know that the image file burned into ROM is not exactly the same as the ARM program in actual operation. Therefore, it is necessary to understand how the ARM program goes from the image in ROM to the actual running state.          


 3; ZI           

    (4) ROM mainly refers to: NAND Flash, Nor Flash           

For those who have just learned ARM, if they analyze its startup code, they often do not understand the meaning of the following variables: |Image$$RO$$Limit|, |Image$$RW$$Base|, |Image$$ZI$$Base|.

After the program is written, it is time to compile and link. Select the MAKE button in ADS1.2, and an Errors and Warnings dialog box will appear. The results of the compilation and linking will be displayed in this column. If there are no errors, you should be able to see Image component sizes at the end of the file, followed by the number of bytes of each item, Code, RO Data, RW Data, ZI Data, and Debug, and finally a statistical data of them:

Code 163632, RO Data 20939, RW Data 53, ZI Data 17028

Tatal RO size (Code+ RO Data) 184571 (180.25kB)

Tatal RW size(RW Data+ ZI Data) 17081(16.68 kB)

Tatal ROM size(Code+ RO Data+ RW Data) 184624(180.30 kB)

The number of bytes following this is based on the user's different programs. The following will use the above data as an example to explain the calculation of those variables.

     In the Debug Settings of ADS, there is a column called Linker/ARM Linker. In the output option, there is an RO base option.

  If the RO base is set to 0x0c100000, and the subsequent RW base is set to 0x0c200000, then there is an Image entry point in the Options option, which is the entry address of the initial program and is set to 0x0c100000.

With the above information, we can fully understand how these variables come from:

|Image$$RO$$Base| = Image entry point =RO base =0x0c100000 ; indicates the starting address where the program code is stored

|Image$$RO$$Limit|=program code starting address + code length + 1

                 = 0x0c100000 + 184571 + 1 = 0x0c100000 +0x2D0FB + 1

                  = 0x0c12d0fc

|Image$$RW$$Base| = 0x0c200000=RW base address specified

|Image$$RW$$Limit| =|Image$$RW$$Base|+ RW Data 53

                   =0x0c200037

|Image$$ZI$$Base| = |Image$$RW$$Limit| + 1 =0x0c200038

|Image$$ZI$$Limit| = |Image$$ZI$$Base| + ZI Data 17028

                   =0x0c200038 + 0x4284

                   =0x0c2042bc

It can also be calculated from:

|Image$$ZI$$Limit| = |Image$$RW$$Base| +TatalRWsize(RWData+ZIData) 17081

                   =0x0c200000+0x42b9+3 (must be a multiple of 4)

                   =0x0c2042bc

Keywords:bootloader  ARM Reference address:bootloader and RO, RW, ZI in ARMC language

Previous article:ARM architecture version and corresponding kernel name
Next article:Simple recording of system clock and timer

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号