基于IMX6Q的uboot启动流程分析(3):_main函数之relocate_code与board_init_r
基于IMX6Q的uboot启动流程分析(1):uboot入口函数
基于IMX6Q的uboot启动流程分析(2):_main函数之board_init_f
基于IMX6Q的uboot启动流程分析(3):_main函数之relocate_code与board_init_r
基于IMX6Q的uboot启动流程分析(4):uboot中的串口设备
第3章:_main函数之relocate_code与board_init_r
3.1 relocate_code函数
上一小节,介绍了board_init_f
函数,主要的是对整个DRAM的内存进行了分配,以便uboot的重定位。
3.1.1 设置中间环境
在调用relocate_code
函数前,需设置中间环境,更新分配DRAM后的sp指针值和gd指针值,其内容如下
ldr r0, [r9, #GD_START_ADDR_SP] /* sp = gd->start_addr_sp */ //新的spbic r0, r0, #7 /* 8-byte alignment for ABI compliance */mov sp, r0ldr r9, [r9, #GD_NEW_GD] /* r9 <- gd->new_gd */adr lr, hereldr r0, [r9, #GD_RELOC_OFF] /* r0 = gd->reloc_off */add lr, lr, r0
#if defined(CONFIG_CPU_V7M)orr lr, #1 /* As required by Thumb-only */
#endifldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */b relocate_code
将新的sp地址赋值给r0 = 0x4DF68F50
3.1.2 relocate_code函数详解
uboot重定位主要由relocate_code
函数实现,其定义在arch/arm/lib/relocate.S
文件中,内容为:
80 ENTRY(relocate_code)81 ldr r1, =__image_copy_start /* r1 <- SRC &__image_copy_start */82 subs r4, r0, r1 /* r4 <- relocation offset */83 beq relocate_done /* skip relocation */84 ldr r2, =__image_copy_end /* r2 <- SRC &__image_copy_end */85 86 copy_loop:87 ldmia r1!, {r10-r11} /* copy from source address [r1] */88 stmia r0!, {r10-r11} /* copy to target address [r0] */89 cmp r1, r2 /* until source end address [r2] */90 blo copy_loop91 92 /*93 * fix .rel.dyn relocations94 */95 ldr r2, =__rel_dyn_start /* r2 <- SRC &__rel_dyn_start */96 ldr r3, =__rel_dyn_end /* r3 <- SRC &__rel_dyn_end */97 fixloop:98 ldmia r2!, {r0-r1} /* (r0,r1) <- (SRC location,fixup) */99 and r1, r1, #0xff
100 cmp r1, #R_ARM_RELATIVE
101 bne fixnext
102
103 /* relative fix: increase location by offset */
104 add r0, r0, r4
105 ldr r1, [r0]
106 add r1, r1, r4
107 str r1, [r0]
108 fixnext:
109 cmp r2, r3
110 blo fixloop
111
112 relocate_done:
113
114 #ifdef __XSCALE__
115 /*
116 * On xscale, icache must be invalidated and write buffers drained,
117 * even with cache disabled - 4.2.7 of xscale core developer's manual
118 */
119 mcr p15, 0, r0, c7, c7, 0 /* invalidate icache */
120 mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */
121 #endif
122
123 /* ARMv4- don't know bx lr but the assembler fails to see that */
124
125 #ifdef __ARM_ARCH_4__
126 mov pc, lr
127 #else
128 bx lr
129 #endif
130
131 ENDPROC(relocate_code)
第81行,将__image_copy_start的值赋值给r1寄存器。由
uboot.map
文件得知__image_copy_start = 0x17800000
第82行,r4寄存器保存重定位前后位置的偏移量。r4 = r0 - r1 = 0x4DF68F50 - 0x17800000 = 0x36768F50。
第83行,跳转
relocate_done
函数,判断uboot重定位的目的地址是否和uboot源地址是否相等,如果相等的话,表示不需要重定位,跳到relocate_done处,继续运行,如果不相等的话,则是需要进行重定位。第84行,r2寄存器保存uboot复制结束的地址
__image_copy_end
。由uboot.map文件得知,__image_copy_end = 0x1787ba9c。第86-90行,
copy_loop
区域,执行拷贝,将uboot从低地址重定位到高地址。重定位过程描述为:- 第一:从r1,也就是__image_copy_start开始,读取uboot代码到r10和r11寄存器,一次就拷贝两个32位的数据,r1自动更新,保存下一个需要拷贝的地址,
- 第二:将r10和r11里面的数据,写到r0保存的地址,也就是uboot重定位的目的地址,r0自动更新。
- 第三:比较r1和r2是否相等,也就是判断uboot代码是否拷贝完成,如果没完成的话,跳转到copy_loop处,继续循环,直到uboot拷贝完成。
第95-110行,重定位.rel.dyn段,.rel.dyn段是存放.text段中需要重定位地址的集合。
补充:
一个可执行的bin文件,它的链接地址和运行地址一定要相等,也就是链接到哪个地址,运行之前就需要拷贝到哪个地址中进行运行,在前面的重定位后,运行地址和链接地址就不一样了,这样在进行寻址就会出问题,对.rel.dyn的定位问题进行修复,就是为了解决该问题。
至此uboot的重定位工作已经完成,将保存在低地址的uboot,自搬移到高地址中执行。
3.1.3 relocate_vectors函数详解
在重定位uboot后,需要调用relocate_vectors
函数,来重定位向量表。函数内容为:
ENTRY(relocate_vectors)#ifdef CONFIG_CPU_V7M/** On ARMv7-M we only have to write the new vector address* to VTOR register.*/ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */ldr r1, =V7M_SCB_BASEstr r0, [r1, V7M_SCB_VTOR]
#else
#ifdef CONFIG_HAS_VBAR/** If the ARM processor has the security extensions,* use VBAR to relocate the exception vectors.*/ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */mcr p15, 0, r0, c12, c0, 0 /* Set VBAR */
#else...
#endif
#endifbx lrENDPROC(relocate_vectors)
在IMX6Q中,定义了CONFIG_HAS_VBAR
,因此这个函数只用执行以下语句:
ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */mcr p15, 0, r0, c12, c0, 0 /* Set VBAR */
首先是将gd->relocaddr的值赋给r0,也就是r0里面保存重定位后uboot的首地址,中断向量表也是从这个首地址开始存储的,接下来,使用mcr指令,将r0的值写到CP15的VBAR寄存器中,其实就是将新的中断向量表首地址写到VBAR寄存器中,设置中断向量表偏移。
至此uboot的重定位与中断向量表重定位的工作已经完成。
3.2 board_init_r函数
2.1节对board_init_f
函数进行介绍,其作用gd结构体的成员变量,以及对DRAM内存进行规划。而本节board_init_r
函数是将一些板子需要的外设进行初始化。
3.2.1 设置board_init_r环境
调用board_init_r函数前,需要设置一些参数,其代码为:
bl c_runtime_cpu_setup /* we still call old routine here */
#endif
#if !defined(CONFIG_SPL_BUILD) || CONFIG_IS_ENABLED(FRAMEWORK)#if !defined(CONFIG_SPL_BUILD) || !defined(CONFIG_SPL_EARLY_BSS)CLEAR_BSS
#endif...
#if ! defined(CONFIG_SPL_BUILD)bl coloured_LED_initbl red_led_on
#endif/* call board_init_r(gd_t *id, ulong dest_addr) */mov r0, r9 /* gd_t */ldr r1, [r9, #GD_RELOCADDR] /* dest_addr *//* call board_init_r */
#if CONFIG_IS_ENABLED(SYS_THUMB_BUILD)ldr lr, =board_init_r /* this is auto-relocated! */bx lr
#elseldr pc, =board_init_r /* this is auto-relocated! */
#endif/* we should not return here. */
#endif
首先是调用了函数c_runtime_cpu_setup
函数,关闭cache。然后调用CLEAR_BSS
清除bss段。接着将gd
地址赋值给r0,将gd->relocaddr
地址赋值给r1。board_init_r(gd_t *id, ulong dest_addr)
函数具有两个参数,第一个参数为gd
指针的值,第二个参数为gd->relocaddr
。最后跳转到board_init_r
函数执行。
3.2.2 board_init_r函数详解
board_init_r
函数定义在common/board_r.c
文件中。函数的主要内容为:
void board_init_r(gd_t *new_gd, ulong dest_addr)
{...
#ifdef CONFIG_NEEDS_MANUAL_RELOCint i;
#endif#if !defined(CONFIG_X86) && !defined(CONFIG_ARM) && !defined(CONFIG_ARM64)gd = new_gd;
#endifgd->flags &= ~GD_FLG_LOG_READY;#ifdef CONFIG_NEEDS_MANUAL_RELOCfor (i = 0; i < ARRAY_SIZE(init_sequence_r); i++)init_sequence_r[i] += gd->reloc_off;
#endifif (initcall_run_list(init_sequence_r))hang();/* NOTREACHED - run_main_loop() does not return */hang();
}
该函数的重点是initcall_run_list(init_sequence_r)
,init_sequence_r
是一个函数集合的数组,也就是函数初始化序列。其内容为:
641 static init_fnc_t init_sequence_r[] = { //函数初始化序列
642 initr_trace,
643 initr_reloc,
644 /* TODO: could x86/PPC have this also perhaps? */
645 #ifdef CONFIG_ARM
646 initr_caches,
647 /* Note: For Freescale LS2 SoCs, new MMU table is created in DDR.
648 * A temporary mapping of IFC high region is since removed,
649 * so environmental variables in NOR flash is not available
650 * until board_init() is called below to remap IFC to high
651 * region.
652 */
653 #endif
654 initr_reloc_global_data,
655 #if defined(CONFIG_SYS_INIT_RAM_LOCK) && defined(CONFIG_E500)
656 initr_unlock_ram_in_cache,
657 #endif
658 initr_barrier,
659 initr_malloc,
660 log_init,
661 initr_bootstage, /* Needs malloc() but has its own timer */
662 #if defined(CONFIG_CONSOLE_RECORD)
663 console_record_init,
664 #endif
665 #ifdef CONFIG_SYS_NONCACHED_MEMORY
666 noncached_init,
667 #endif
668 initr_of_live,
669 #ifdef CONFIG_DM
670 initr_dm,
671 #endif
672 #ifdef CONFIG_ADDR_MAP
673 initr_addr_map,
674 #endif
675 #if defined(CONFIG_ARM) || defined(CONFIG_NDS32) || defined(CONFIG_RISCV) || \
676 defined(CONFIG_SANDBOX)
677 board_init, /* Setup chipselects */
678 #endif
679 /*
680 * TODO: printing of the clock inforamtion of the board is now
681 * implemented as part of bdinfo command. Currently only support for
682 * davinci SOC's is added. Remove this check once all the board
683 * implement this.
684 */
685 #ifdef CONFIG_CLOCKS
686 set_cpu_clk_info, /* Setup clock information */
687 #endif
688 #ifdef CONFIG_EFI_LOADER
689 efi_memory_init,
690 #endif
691 initr_binman,
692 #ifdef CONFIG_FSP_VERSION2
693 arch_fsp_init_r,
694 #endif
695 initr_dm_devices,
696 stdio_init_tables,
697 serial_initialize,
698 initr_announce,
699 #if CONFIG_IS_ENABLED(WDT)
700 initr_watchdog,
701 #endif
702 INIT_FUNC_WATCHDOG_RESET
703 #if defined(CONFIG_NEEDS_MANUAL_RELOC) && defined(CONFIG_BLOCK_CACHE)
704 blkcache_init,
705 #endif
706 #ifdef CONFIG_NEEDS_MANUAL_RELOC
707 initr_manual_reloc_cmdtable,
708 #endif
709 arch_initr_trap,
710 #if defined(CONFIG_BOARD_EARLY_INIT_R)
711 board_early_init_r,
712 #endif
713 INIT_FUNC_WATCHDOG_RESET
714 #ifdef CONFIG_POST
715 post_output_backlog,
716 #endif
717 INIT_FUNC_WATCHDOG_RESET
718 #if defined(CONFIG_PCI_INIT_R) && defined(CONFIG_SYS_EARLY_PCI_INIT)
719 /*
720 * Do early PCI configuration _before_ the flash gets initialised,
721 * because PCU resources are crucial for flash access on some boards.
722 */
723 pci_init,
724 #endif
725 #ifdef CONFIG_ARCH_EARLY_INIT_R
726 arch_early_init_r,
727 #endif
728 power_init_board,
729 #ifdef CONFIG_MTD_NOR_FLASH
730 initr_flash,
731 #endif
732 INIT_FUNC_WATCHDOG_RESET
733 #if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_X86)
734 /* initialize higher level parts of CPU like time base and timers */
735 cpu_init_r,
736 #endif
737 #ifdef CONFIG_CMD_NAND
738 initr_nand,
739 #endif
740 #ifdef CONFIG_CMD_ONENAND
741 initr_onenand,
742 #endif
743 #ifdef CONFIG_MMC
744 initr_mmc,
745 #endif
746 #ifdef CONFIG_XEN
747 xen_init,
748 #endif
749 #ifdef CONFIG_PVBLOCK
750 initr_pvblock,
751 #endif
752 initr_env,
753 #ifdef CONFIG_SYS_BOOTPARAMS_LEN
754 initr_malloc_bootparams,
755 #endif
756 INIT_FUNC_WATCHDOG_RESET
757 cpu_secondary_init_r,
758 #if defined(CONFIG_ID_EEPROM) || defined(CONFIG_SYS_I2C_MAC_OFFSET)
759 mac_read_from_eeprom,
760 #endif
761 INIT_FUNC_WATCHDOG_RESET
762 #if defined(CONFIG_PCI_INIT_R) && !defined(CONFIG_SYS_EARLY_PCI_INIT)
763 /*
764 * Do pci configuration
765 */
766 pci_init,
767 #endif
768 stdio_add_devices,
769 jumptable_init,
770 #ifdef CONFIG_API
771 api_init,
772 #endif
773 console_init_r, /* fully init console as a device */
774 #ifdef CONFIG_DISPLAY_BOARDINFO_LATE
775 console_announce_r,
776 show_board_info,
777 #endif
778 #ifdef CONFIG_ARCH_MISC_INIT
779 arch_misc_init, /* miscellaneous arch-dependent init */
780 #endif
781 #ifdef CONFIG_MISC_INIT_R
782 misc_init_r, /* miscellaneous platform-dependent init */
783 #endif
784 INIT_FUNC_WATCHDOG_RESET
785 #ifdef CONFIG_CMD_KGDB
786 initr_kgdb,
787 #endif
788 interrupt_init,
789 #if defined(CONFIG_MICROBLAZE) || defined(CONFIG_M68K)
790 timer_init, /* initialize timer */
791 #endif
792 #if defined(CONFIG_LED_STATUS)
793 initr_status_led,
794 #endif
795 /* PPC has a udelay(20) here dating from 2002. Why? */
796 #ifdef CONFIG_CMD_NET
797 initr_ethaddr,
798 #endif
799 #if defined(CONFIG_GPIO_HOG)
800 gpio_hog_probe_all,
801 #endif
802 #ifdef CONFIG_BOARD_LATE_INIT
803 board_late_init,
804 #endif
805 #ifdef CONFIG_FSL_FASTBOOT
806 initr_fastboot_setup,
807 #endif
808 #if defined(CONFIG_SCSI) && !defined(CONFIG_DM_SCSI)
809 INIT_FUNC_WATCHDOG_RESET
810 initr_scsi,
811 #endif
812 #ifdef CONFIG_BITBANGMII
813 bb_miiphy_init,
814 #endif
815 #ifdef CONFIG_PCI_ENDPOINT
816 pci_ep_init,
817 #endif
818 #ifdef CONFIG_CMD_NET
819 INIT_FUNC_WATCHDOG_RESET
820 initr_net,
821 #endif
822 #ifdef CONFIG_POST
823 initr_post,
824 #endif
825 #if defined(CONFIG_IDE) && !defined(CONFIG_BLK)
826 initr_ide,
827 #endif
828 #ifdef CONFIG_LAST_STAGE_INIT
829 INIT_FUNC_WATCHDOG_RESET
830 /*
831 * Some parts can be only initialized if all others (like
832 * Interrupts) are up and running (i.e. the PC-style ISA
833 * keyboard).
834 */
835 last_stage_init,
836 #endif
837 #ifdef CONFIG_CMD_BEDBUG
838 INIT_FUNC_WATCHDOG_RESET
839 bedbug_init,
840 #endif
841 #if defined(CONFIG_PRAM)
842 initr_mem,
843 #endif
844 #ifdef CONFIG_EFI_SETUP_EARLY
845 (init_fnc_t)efi_init_obj_list,
846 #endif
847 #if defined(AVB_RPMB) && !defined(CONFIG_SPL)
848 initr_avbkey,
849 #endif
850 #ifdef CONFIG_IMX_TRUSTY_OS
851 initr_tee_setup,
852 #endif
853 #ifdef CONFIG_FSL_FASTBOOT
854 initr_check_fastboot,
855 #endif
856 #ifdef CONFIG_DUAL_BOOTLOADER
857 initr_check_spl_recovery,
858 #endif
859 run_main_loop,
860 };
第642行,
initr_trace
,该函数是与初始化和调试跟踪相关的内容。第643行,
initr_reloc
,该函数设置了gd->flags成员,标记uboot重定位完成。第646行,
initr_reloc
,该函数用于初始化cache,使能cache。第654行,
initr_reloc_global_data
,该函数用于初始化重定为后gd的一些成员变量。。第659行,
initr_malloc
,该函数用于初始化malloc。int board_init(void) {/* address of boot parameters */gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;#if defined(CONFIG_DM_REGULATOR)regulators_enable_boot_on(false); #endif#ifdef CONFIG_MXC_SPIsetup_spi(); #endif#ifdef CONFIG_SYS_I2Csetup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1); #endif#if defined(CONFIG_PCIE_IMX) && !defined(CONFIG_DM_PCI)setup_pcie(); #endif#if defined(CONFIG_MX6DL) && defined(CONFIG_MXC_EPDC)setup_epdc(); #endif#ifdef CONFIG_FEC_MXCsetup_fec(); #endifreturn 0; }
第696行,
stdio_init_tables
,该函数用于stdio相关初始化。第 697行,
serial_initialize
,该函数初始化串口相关东西。第738行,
initr_nand
,该函数用于nand flash初始化,需要时调用。第744行,
initr_mmc
,该函数用来初始化和sd/mmc相关的接口,实际调用mmc_initialize
函数实现,定义在drivers/mmc/mmc.c
文件中,其内容为:int mmc_initialize(struct bd_info *bis) {static int initialized = 0;int ret;if (initialized) /* Avoid initializing mmc multiple times */return 0;initialized = 1;#if !CONFIG_IS_ENABLED(BLK) #if !CONFIG_IS_ENABLED(MMC_TINY)mmc_list_init(); #endif #endifret = mmc_probe(bis);if (ret)return ret;#ifndef CONFIG_SPL_BUILDprint_mmc_devices(','); #endifmmc_do_preinit();return 0; }
第744行,
initr_env
,该函数用来初始化环境变量。第768行,
stdio_add_devices
,该函数用于初始化各种输入输出设备,例如LCD相关的设备。第769行,
stdio_add_devices
,该函数用来初始化跳转表相关的内容。第78行,
interrupt_init
,该函数用来初始化中断相关内容。IMX6Q为空,需要时使用。第797行,
interrupt_init
,该函数用于初始化网络地址,用于获取网卡的MAC地址。第803行,
board_late_init
,该函数用于板级后续的一些外设初始化。第806行,
initr_fastboot_setup
,初始化fastboot。第820行,
initr_net
,初始化以太网,实际调用eth_initialize
函数实现,其定义在net/eth-uclass.c
文件。第859行,
run_main_loop
,该函数主循环函数,用于处理输入的命令,也就是uboot进入了命令行终端模式,内容为:static int run_main_loop(void) {#ifdef CONFIG_SANDBOXsandbox_main_loop_init(); #endif/* main_loop() can return to retry autoboot, if so just run it again */for (;;)main_loop();return 0; }
函数在无线循环执行
main_loop
函数,此函数将在下一小节详细介绍。至此
board_init_r
函数介绍完,主要是完成一些需要的外设初始化,不同的板子,会进行不同的初始化。
3.2.3 main_loop函数
main_loop
函数主要作用是实现目标板与人的交互,其定义在common/main.c
文件中,内容为:
40 void main_loop(void)41 {42 const char *s;43 44 bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop");45 46 if (IS_ENABLED(CONFIG_VERSION_VARIABLE))47 env_set("ver", version_string); /* set version variable */48 49 cli_init();50 51 if (IS_ENABLED(CONFIG_USE_PREBOOT))52 run_preboot_environment_command();53 54 if (IS_ENABLED(CONFIG_UPDATE_TFTP))55 update_tftp(0UL, NULL, NULL);56 57 if (IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK_EARLY))58 efi_launch_capsules();59 60 s = bootdelay_process();61 if (cli_process_fdt(&s))62 cli_secure_boot_cmd(s);63 64 autoboot_command(s);65 66 cli_loop();67 panic("No CLI available");68 }
第60行,
bootdelay_process
,该函数获取bootdelay
和bootcmd
参数的内容,返回值为环境变量bootcmd
的值。第64行,
autoboot_command
,该函数的作用是,用于检测u-boot启动过程中的倒计时过程是否结束。倒计时结束之前是否被打断。函数定义在文件common/autoboot.c
,其内容为:void autoboot_command(const char *s) {debug("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>");if (s && (stored_bootdelay == -2 ||(stored_bootdelay != -1 && !abortboot(stored_bootdelay)))) {bool lock;int prev;lock = IS_ENABLED(CONFIG_AUTOBOOT_KEYED) &&!IS_ENABLED(CONFIG_AUTOBOOT_KEYED_CTRLC);if (lock)prev = disable_ctrlc(1); /* disable Ctrl-C checking */run_command_list(s, -1, 0);if (lock)disable_ctrlc(prev); /* restore Ctrl-C checking */}if (IS_ENABLED(CONFIG_USE_AUTOBOOT_MENUKEY) &&menukey == AUTOBOOT_MENUKEY) {s = env_get("menucmd");if (s)run_command_list(s, -1, 0);} }
如果倒计时正常结束,那么将执行
run_command_list
,此函数会执行参数s指定的一系列命令,也就是bootcmd
中配置中的命令,一般配置为linux内核启动命令,因此linux内核启动。如果在倒计时结束前按下回车键,
run_command_list
就不会执行,autoboot_command
相当于空函数。run_command_list
函数定义在common/cli.c
文件,其内容为:int run_command_list(const char *cmd, int len, int flag) {int need_buff = 1;char *buff = (char *)cmd; /* cast away const */int rcode = 0;if (len == -1) {len = strlen(cmd); #ifdef CONFIG_HUSH_PARSER/* hush will never change our string */need_buff = 0; #else/* the built-in parser will change our string if it sees \n */need_buff = strchr(cmd, '\n') != NULL; #endif}if (need_buff) {buff = malloc(len + 1);if (!buff)return 1;memcpy(buff, cmd, len);buff[len] = '\0';} #ifdef CONFIG_HUSH_PARSERrcode = parse_string_outer(buff, FLAG_PARSE_SEMICOLON); #else #ifdef CONFIG_CMDLINErcode = cli_simple_run_command_list(buff, flag); #elsercode = board_run_command(buff); #endif #endifif (need_buff)free(buff);return rcode; }
主要工作内容为,调用
parse_string_outer
函数解析并执行bootcmd
中配置中的命令。第66行,
cli_init
,该函数是uboot命令行处理函数,输入的各种命令,进行各种操作就是cli_loop
函数来处理的,函数处理过程比较复杂,就不单独分析。
至此整个uboot2021启动流程分析完成,下面介绍uboot中的串口模块。
基于IMX6Q的uboot启动流程分析(3):_main函数之relocate_code与board_init_r相关推荐
- u-boot启动流程分析
u-boot启动流程分析 以smdk2410为例,分析u-boot的启动流程.u-boot的启动流程是指从cpu上电开机执行u-boot到u-boot成功加载完操作系统的过程.这一过程可以分为两个阶段 ...
- Exynos4412 Uboot 移植(二)—— Uboot 启动流程分析
uboot启动流程分析如下: 第一阶段: a -- 设置cpu工作模式为SVC模式 b -- 关闭中断,mmu,cache v -- 关看门狗 d -- 初始化内存,串口 e -- 设置栈 f -- ...
- 基于 LPC1114 的 M0 启动流程分析
基于LPC1114的M0启动流程分析 作者:解琛 时间:2020 年 8 月 1 日 基于LPC1114的M0启动流程分析 一..s 启动进程 1.1 堆栈配置 1.2 中断向量表 1.3 定义中断服 ...
- u-boot启动流程分析(1)_平台相关部分
转自:http://www.wowotech.net/u-boot/boot_flow_1.html 1. 前言 本文将结合u-boot的"board->machine->arc ...
- linux uboot启动流程分析,uboot启动流程分析
uboot版本为NXP维护的2016.03版本 下载地址为http://git.freescale.com/git/... 分析uboot的启动流程,需要编译一下uboot,然后打开链接脚本 u-bo ...
- am335x uboot启动流程分析
基本指令含义 .globl _start .globl指示告诉汇编器,_start这个符号要被链接器用到,所以要在目标文件的符号表中标记它是一个全局符号 b,bl b是不带返回的跳转 bl带返回的跳 ...
- U-BOOT学习之2014.4版Uboot启动流程分析
一.前言 老大给我布置了一个任务:某某项目uboot开发之usb增强ic驱动. 不知道大家看到这个任务懵不懵,反正我最开始是蒙的.后来又问了一下,才明白到底要做啥. 任务是这样的:因为这个项目的usb ...
- Uboot 启动流程分析
uboot启动流程 复位CPU 设置异常向量表 设置cpu为SVC模式 但是从U-Boot方面考虑,其要做的事情是初始化系统的相关硬件资源,因此需要获取尽量多的权限,以方便操作硬件,初始化硬件. 关闭 ...
- 2014.4新版uboot启动流程分析
原文 http://blog.csdn.net/skyflying2012/article/details/25804209 此处转载有稍作修改 最近开始接触uboot,现在需要将2014.4版本ub ...
最新文章
- 搭建Ubuntu18.04+Anaconda3.x+Pycharm+SimpleITK(三)
- 2020-12-09 深度学习 卷积神经网络中感受野的详细介绍
- MapReduce Java API实例-统计单词出现频率
- DAG的深度优先搜索标记
- 2020CCPC威海
- 共享单车变“私有”、被毁、被盗:用户们都看不下去了,举报!
- cesium three性能比较_硬金和千足金都是黄金,哪个比较好?为什么80%人都说硬金不好?...
- FastDfs工作笔记002---SpringBoot集成FastDfs
- Kafka和Unix管道的示例
- H5和小程序区别详解
- cad插件加载bplot成功用不了_Batchplot批量打印命令无效,对照情况进行解决
- linux 备份 网络配置,如何备份已经配置好的虚拟机linux系统的网络..._网络编辑_帮考网...
- linux系统下回收站,Linux怎么开启回收站功能
- Dynamic Head: Unifying Object Detection Heads with Attentions
- 深度学习需要多强的数学基础?
- 不定积分 定积分 计算方法
- 微信小程序人脸核身---快速入门到实战(附开发工具类,复制即用)
- 商用向南,家用向北丨DOMOTEX asia 2020地毯馆大布局
- Leetcode 905 c#
- 为什么收藏了这么多3D游戏建模教程,还是没达到可以就业接包的水准?
热门文章
- 中国唯一的图灵奖获得者姚期智,在清华开设的“姚班”有哪些 AI 名徒?
- android apk 永久root,Android 实现永久性开启adb 的root权限
- 计算机三级网络技术最全知识点总结三
- vue3基础 —— 子传父
- 字母c代表什么数字_字母C
- 实战PyQt5: 130-使用HTTP请求下载文件
- linux shell脚本攻略 第三章 以文件之名 find,chmod,touch,head,tail,tree,wc
- JSP起源、JSP的运行原理、JSP的执行过程
- 微信公众号--发送模板消息
- Maya角色UV展平技巧笔记