MTK bootloader startup process

tags:  MTK

1, bootloader to kernel start total logic flow chart

ARMArchitectureIn EL0/EL1, EL2/EL1 is required, EL2/EL3 is optional, and ELx is hierarchically related:

EL0 -- app

EL1 -- Linux kernel 銆乴k

EL2 -- hypervisor (virtualization)

EL3 -- ARM trust firmware 銆乸re-loader

If the platform does not implement EL3(atf), the pre-loader loads lk directly:

 

If the platform implements EL3, you need to load the ATF first and then load the lk by the ATF:

The bootloader starts in two phases.One is the pre-loader loading lk (u-boot) phase, and the other is the lk loading kernel phase.. The following is a brief description of the loading process of the first phase.

1-3: After the device is powered on, jump to the boot code in the Boot ROM (not flash) to load the pre-loader into ISRAM, because the current DRAM (RAM is divided into SRAM and DRAM, simply SRAM is the cache. , DRAM is ordinary memory) is not ready, so first load the pre-loader into the ISRAM (Internal SRAM) inside the chip.

4-6: After the pre-loader initializes the DRAM, it loads the lk from the flash (nand/emmc) into the DRAM;

7-8: Decompress bootimage into ramdisk and kernel and load into DRAM, initialize dtb;

9-11: lk jumps to kernl initialization, after the kernel initialization is completed, fork out the init process, and then pulls up the init program in ramdisk, enters user space initialization, init process forks out zygote process.. until the wholeAndroidThe startup is complete.

 

2, from pre-loader to lk (mt6580 as an example)

The main thing Pre-loader does is to initialize some hardware, such as: UART, GPIO, DRAM, TIMER, RTC, PMIC, etc., to establish the most basic operating environment, the most important thing is to initialize DRAM.

Timing diagram:

Click for larger image

The source code process is as follows:

 
  1. ./bootloader/preloader/platform/mt6580/src/init/init.s

  2.  
  3. .section .text.start

  4. ...

  5.  
  6. .globl _start

  7. ...

  8.  
  9. /* set the cpu to SVC32 mode */

  10. MRS r0,cpsr

  11. BIC r0,r0,#0x1f

  12. ORR r0,r0,#0xd3

  13. MSR cpsr,r0

  14.  
  15. /* disable interrupt */

  16. MRS r0, cpsr

  17. MOV r1, #INT_BIT

  18. ORR r0, r0, r1

  19. MSR cpsr_cxsf, r0

  20.  
  21. ...

  22. setup_stk :

  23. /* setup stack */

  24. LDR r0, stack

  25. LDR r1, stacksz

  26. ...

  27.  
  28. entry :

  29. LDR r0, =bldr_args_addr

  30.  
  31. /* Jump to C code main entry */

  32. B main

The main thing in init.s is to switch the system to management mode (svc) (if the platform has el3, then the pre-loader runs on el3, otherwise it runs on el1), irq/fiq is disabled, stack is set, etc., then jump to c The code main function entry.

Enter the source code analysis.

 
  1. ./bootloader/preloader/platform/mt6580/src/core/main.c

  2.  
  3. void main(u32 *arg)

  4. {

  5. struct bldr_command_handler handler;

  6. u32 jump_addr, jump_arg;

  7.  
  8. /* get the bldr argument */

  9. bldr_param = (bl_param_t *)*arg;

  10.  
  11. // Initialize uart

  12. mtk_uart_init(UART_SRC_CLK_FRQ, CFG_LOG_BAUDRATE);

  13.  
  14. // There are a lot of things done here, including various platform hardware (timer, pmic, gpio, wdt...) initialization work.

  15. bldr_pre_process();

  16.  
  17. handler.priv = NULL;

  18. handler.attr = 0;

  19. handler.cb = bldr_cmd_handler;

  20.  
  21. // Here is the information to get the startup mode and save it to the global variables g_boot_mode and g_meta_com_type.

  22. BOOTING_TIME_PROFILING_LOG("before bldr_handshake");

  23. bldr_handshake(&handler);

  24. BOOTING_TIME_PROFILING_LOG("bldr_handshake");

  25.  
  26. // The following is related to secro img, which is strongly related to platform design.

  27. /* security check */

  28. sec_lib_read_secro();

  29. sec_boot_check();

  30. device_APC_dom_setup();

  31.  
  32. BOOTING_TIME_PROFILING_LOG("sec_boot_check");

  33.  
  34. /* If EL3 has been implemented, then tz pre-initializes */

  35. #if CFG_ATF_SUPPORT

  36. trustzone_pre_init();

  37. #endif

  38.  
  39. /* bldr_load_images

  40. The thing to do with this function is to load lk from the specified location in ROM to DRAM. You can see the specific information in the boot log:

  41. [PART] load "lk" from 0x0000000001CC0200 (dev) to 0x81E00000 (mem) [SUCCESS]

  42. Here is the specific address of the jump to DRAM, detailed analysis below.

  43. */

  44. if (0 != bldr_load_images(&jump_addr)) {

  45. print("%s Second Bootloader Load Failed\n", MOD);

  46. goto error;

  47. }

  48.  
  49. /*

  50. The implementation of this function is platform_post_init, the thing to do here is actually relatively simple, is through

  51. Hw_check_battery to determine whether there is a battery in the current system (determine whether there is a battery ntc foot to distinguish)

  52. If it doesn't exist, it will get stuck in while(1), so sometimes debugging in es stage

  53. Need to connect to the power supply debugging, you need to change the logic inside to start normally

  54. */

  55. bldr_post_process();

  56.  
  57. // atf is officially initialized and implemented using a unique system call.

  58. #if CFG_ATF_SUPPORT

  59. trustzone_post_init();

  60. #endif

  61.  
  62. /* Jumps the parameters of the incoming lk, including boot time/mode/reason, etc.

  63. The platform_set_boot_args function gets.

  64. */

  65. jump_arg = (u32)&(g_dram_buf->boottag);

  66.  
  67.  
  68. /* Execute the jump system call, jump from pre-loader to lk,

If you realize the EL3 situationMore complicated, you need to jump to EL3 initialization first, then jump back to lk, pre-loader is executed in EL3, LK is executed in EL1)

This information can be seen similarly from the log: [BLDR] jump to 0x81E00000 [BLDR] <0x81E00000>=0xEA000007 [BLDR] <0x81E00004>=0xEA0056E2 */ #if CFG_ATF_SUPPORT /* 64S3,32S1,32S1 (MTK_ATF_BOOT_OPTION = 0) * re -loader jump to LK directly and then LK jump to kernel directly */ if ( BOOT_OPT_64S3 == g_smc_boot_opt && BOOT_OPT_32S1 == g_lk_boot_opt && BOOT_OPT_32S1 == g_kernel_boot_opt) { print("%s 64S3,32S1,32S1, jump to LK\n" , MOD); bldr_jump(jump_addr, jump_arg, sizeof(boot_arg_t)); } else {// If el3 is implemented using aarch64, jump to atf. print("%s Others, jump to ATF\n", MOD); bldr_jump64 (jump_addr, jump_arg, sizeof(boot_arg_t)); } #else bldr_jump(jump_addr, jump_arg, sizeof(boot_arg_t)); #endif // If you do not get jump_addr, print an error message and enter while(1) wait. error: Platform_error_handler(); }

Summary of the main function:

1, various hardware initialization (uart, pmic, wdt, timer, mem..);

2. Obtain the system startup mode, etc., and save it in the global variable;

3, Security check, related to secro.img;

4. If the system has implemented el3, enter tz initialization;

5. Get the address (fixed value) loaded by lk into the DRAM, and then find the address of the lk partition from the ROM. If jump_addr is not found, then goto error;

6, battery check, if there is no battery will fall into while (1);

7, jump to lk (if there is implementation of el3, it will jump to el3, then back to lk)

 

3. Analysis of key functions

bldr_load_images

The main function of the function is to find the address of the lk partition and the address that lk loads into the DRAM, and prepare the jump to lk for execution.The following source code analysis:

 
  1. static int bldr_load_images(u32 *jump_addr)

  2. {

  3. int ret = 0;

  4. blkdev_t *bootdev;

  5. u32 addr = 0;

  6. char *name;

  7. u32 size = 0;

  8. u32 spare0 = 0;

  9. u32 spare1 = 0;

  10.  
  11. ...

  12. /* This address is a fixed value and can be found to be defined in:

  13. ./bootloader/preloader/platform/mt6580/default.mak:95:

  14. CFG_UBOOT_MEMADDR := 0x81E00000

  15. From the log you can see:

  16. [BLDR] jump to 0x81E00000

  17. */

  18. addr = CFG_UBOOT_MEMADDR;

  19.  
  20. /* Then go to the ROM and find the partition address where lk is located */

  21. ret = bldr_load_part("lk", bootdev, &addr, &size);

  22. if (ret)

  23. return ret;

  24. *jump_addr = addr;

  25.  
  26. }

  27.  
  28. // This function logic is very simple, so you don't need to say more.

  29. int bldr_load_part(char *name, blkdev_t *bdev, u32 *addr, u32 *size)

  30. {

  31. part_t *part = part_get(name);

  32.  
  33. if (NULL == part) {

  34. print("%s %s partition not found\n", MOD, name);

  35. return -1;

  36. }

  37.  
  38. return part_load(bdev, part, addr, 0, size);

  39. }

  40.  
  41. // The real load implementation is in the part_load function.

  42. int part_load(blkdev_t *bdev, part_t *part, u32 *addr, u32 offset, u32 *size)

  43. {

  44. int ret;

  45. img_hdr_t *hdr = (img_hdr_t *)img_hdr_buf;

  46. part_hdr_t *part_hdr = &hdr->part_hdr;

  47. gfh_file_info_t *file_info_hdr = &hdr->file_info_hdr;

  48.  
  49. /* specify the read offset */

  50. u64 src = part->startblk * bdev->blksz + offset;

  51. u32 dsize = 0, maddr = 0;

  52. u32 ms;

  53.  
  54. // Retrieve the partition header is correct.

  55. /* retrieve partition header. */

  56. if (blkdev_read(bdev, src, sizeof(img_hdr_t), (u8*)hdr,0) != 0) {

  57. print("[%s]bdev(%d) read error (%s)\n", MOD, bdev->type, part->name);

  58. return -1;

  59. }

  60.  
  61. if (part_hdr->info.magic == PART_MAGIC) {

  62.  
  63. /* load image with partition header */

  64. part_hdr->info.name[31] = '\0';

  65.  
  66. /*

  67. Various information about the output partition, you can see from the log:

  68. [PART] Image with part header

  69. [PART] name : lk

  70. [PART] addr : FFFFFFFFh mode : -1

  71. [PART] size : 337116

  72. [PART] magic: 58881688h

  73. */

  74. print("[%s]Img with part header\n", MOD);

  75. print("[%s]name:%s\n", MOD, part_hdr->info.name);

  76. print("[%s]addr:%xh\n", MOD, part_hdr->info.maddr);

  77. print("[%s]size:%d\n", MOD, part_hdr->info.dsize);

  78. print("[%s]magic:%xh\n", MOD, part_hdr->info.magic);

  79.  
  80. maddr = part_hdr->info.maddr;

  81. dsize = part_hdr->info.dsize;

  82. src += sizeof(part_hdr_t);

  83.  
  84. memcpy(part_info + part_num, part_hdr, sizeof(part_hdr_t));

  85. part_num++;

  86. } else {

  87. print("[%s]%s img not exist\n", MOD, part->name);

  88. return -1;

  89. }

  90.  
  91. // If maddr is not defined, then the address incoming addr is used.

  92. if (maddr == PART_HEADER_MEMADDR/*0xffffffff*/)

  93. maddr = *addr;

  94.  
  95. if_overlap_with_dram_buffer((u32)maddr, ((u32)maddr + dsize));

  96.  
  97. ms = get_timer(0);

  98. if (0 == (ret = blkdev_read(bdev, src, dsize, (u8*)maddr,0)))

  99. *addr = maddr;

  100. ms = get_timer(ms);

  101.  
  102. /* If all goes well, it will print out key information:

  103. [PART] load "lk" from 0x0000000001CC0200 (dev) to 0x81E00000 (mem) [SUCCESS]

  104. [PART] load speed: 25324KB/s, 337116 bytes, 13ms

  105. */

  106. print("\n[%s]load \"%s\" from 0x%llx(dev) to 0x%x (mem) [%s]\n", MOD,

  107. part->name, src, maddr, (ret == 0) ? "SUCCESS" : "FAILED");

  108.  
  109. if( ms == 0 )

  110. ms+=1;

  111.  
  112. print("[%s]load speed:%dKB/s,%d bytes,%dms\n", MOD, ((dsize / ms) * 1000) / 1024, dsize, ms);

  113.  
  114.  
  115. return ret;

  116. }

bldr_post_process

The main thing that the function does is to check if there is a battery from pmic, if not, wait, the following source code analysis, relatively simple:

 
  1. // It's just a layer.

  2. static void bldr_post_process(void)

  3. {

  4. platform_post_init();

  5. }

  6.  
  7. // The focus is on this function:

  8. void platform_post_init(void)

  9. {

  10. /* normal boot to check battery exists or not */

  11. if (g_boot_mode == NORMAL_BOOT && !hw_check_battery() && usb_accessory_in()) {

  12. ...

  13. pl_charging(1);

  14. do {

  15. mdelay(300);

  16.  
  17. /* Check if the battery is present. If you use power debugging, you need to modify this function logic */

  18. if (hw_check_battery())

  19. break;

  20. /* Feed the dog to avoid being bitten by the dog over time */

  21. platform_wdt_all_kick();

  22. } while(1);

  23. /* disable force charging mode */

  24. pl_charging(0);

  25. }

  26.  
  27. ...

  28. }

Copyright Complaint       Spam Report

Intelligent Recommendation

Start from the MCU to the startup process to write Bootloader (top)

The BOOT of the development board is started from EFLASH (that is, Flash memory in the film). The corresponding settings are also required in the keil. Bootloader to be written next is written to EFLA...

Start from the MCU to the startup process to write bootloader (middle)

The startup process of the MCU power -on has been analyzed above. This article attempts to write a simple Bootloader and an app that implements CAN communication, and pave the way for us to try to wri...

Introduce BootLoader, PM, kernel and the overall process of system startup

BootLoader, PM, kernel and the overall process of system startup 1. Overall start-up process 2. Related subsystems 3. What is done in each link? 4. Introduction to bootloader 1. Commonly used bootload...

Bootloader startup parameter passing

Arm platform The arch/arm/kernel/head.S file defines the parameter transfer requirements for the bootloader and kernel: So in the main entry function of the kernel, you need to pass 3 parameters, r0/r...

Bootloader startup and function

Article Directory Introduction to Bootloader S5P6818 startup process (one pass, one pass) Install the uboot burning tool Introduction to Bootloader Bootloader can be interpreted as starting the boot p...

More Recommendation

MTK platform startup process, based on LK, mt6761 to establish a startup mind map

Start the assembly line: BootRom -----------> Preloader ----------->LK ----------->linux kernel   Here only boot to the kernel, the init process to the Android system to be summarized ne...

[Embedded Development] Bootloader Detailed (Code Environment | ARM Startup Process | uboot Workflow | Architecture Design)...

Author : Han Yuliang blog address : Reprinted please famous source Related resources download: -- U-boot source: -- S3C2440 documentation : --S5PV210_iROM_ApplicationNote_Preliminary_20091126 Document...

bootloader pass startup parameters (b)

1.dtb how is passed to the kernel of? First base dtb is packaged into the kernel with the boot.img, dtbo a separate partition is stored, transmitted to the kernel after integration after loading bootl...

Bootloader startup analysis of xv6 system

Bootloader startup analysis Refer to Appendix B of xv6 https://github.com/ranxian/xv6-chinese/blob/master/content/AppendixB.md The behavior of the hardware after the computer starts Always curious abo...

Introduction to the bootloader process

Bootloader overview From the perspective of software, an embedded Linux system is usually divided into four levels: bootloader, Linux kernel, file system, and user application. In linux, the bootloade...

Copyright   DMCA © 2018-2024 - All Rights Reserved - www.programmersought.com   User Notice

Top

两个鬼故事msci海淘贝水命起名字用什么字好商标起名免费按生辰八字免费起名评分表品牌如何起名马克威廉手写软件工业霸主笔趣阁工程施工流程我新装修了饭店起名在线起英文名网免费取名老虎机怎么玩梓起名字大全卢姓宝宝起名女孩商行起名大全吉利qjwm女孩起什么名字好听起名预测评分表2019猪年的宝宝起名姓方男宝宝起名莽荒纪txt下载易公司起名大全免费物业公司起名好听姓氏郭怎么起名字八卦起名称神枪手与咖喱鸡版本转换器工程公司起名大全自动翻译网页少年生前被连续抽血16次?多部门介入两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”淀粉肠小王子日销售额涨超10倍高中生被打伤下体休学 邯郸通报单亲妈妈陷入热恋 14岁儿子报警何赛飞追着代拍打雅江山火三名扑火人员牺牲系谣言张家界的山上“长”满了韩国人?男孩8年未见母亲被告知被遗忘中国拥有亿元资产的家庭达13.3万户19岁小伙救下5人后溺亡 多方发声315晚会后胖东来又人满为患了张立群任西安交通大学校长“重生之我在北大当嫡校长”男子被猫抓伤后确诊“猫抓病”测试车高速逃费 小米:已补缴周杰伦一审败诉网易网友洛杉矶偶遇贾玲今日春分倪萍分享减重40斤方法七年后宇文玥被薅头发捞上岸许家印被限制高消费萧美琴窜访捷克 外交部回应联合利华开始重组专访95后高颜值猪保姆胖东来员工每周单休无小长假男子被流浪猫绊倒 投喂者赔24万小米汽车超级工厂正式揭幕黑马情侣提车了西双版纳热带植物园回应蜉蝣大爆发当地回应沈阳致3死车祸车主疑毒驾恒大被罚41.75亿到底怎么缴妈妈回应孩子在校撞护栏坠楼外国人感慨凌晨的中国很安全杨倩无缘巴黎奥运校方回应护栏损坏小学生课间坠楼房客欠租失踪 房东直发愁专家建议不必谈骨泥色变王树国卸任西安交大校长 师生送别手机成瘾是影响睡眠质量重要因素国产伟哥去年销售近13亿阿根廷将发行1万与2万面值的纸币兔狲“狲大娘”因病死亡遭遇山火的松茸之乡“开封王婆”爆火:促成四五十对奥巴马现身唐宁街 黑色着装引猜测考生莫言也上北大硕士复试名单了德国打算提及普京时仅用姓名天水麻辣烫把捣辣椒大爷累坏了

两个鬼故事 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化