2回答

0收藏

【DLT-RK3288试用】11,uboot源码分析

其他 其他 7192 人阅读 | 2 人回复 | 2018-07-19

本帖最后由 robe.zhang 于 2018-7-19 01:10 编辑

【DLT-RK3288试用】11,uboot源码分析



看了一遍源码看完了,重点看了启动失败的一部分;
rk3288 有一堆板级文件,是 rockchip 专有的,就是一些img有关存储有关的东西,也没有合入主线;
看了时候做了个记录,以下:
  1. arch/arm/cpu/armv7/start.S:
  2.         全局变量:
  3. Reset
  4.         Rockchip 芯片在开头设置了loader_tag,确认通过的话才能运行,不然死到这里
  5. #ifdef CONFIG_ROCKCHIP
  6. ldr        r0, =__loader_tag
  7. ldr        r1, [r0]
  8. ldr        r0, =LoaderTagCheck
  9. ldr        r0, [r0]
  10. cmp        r1, r0
  11. movne        pc, r14
  12. #endif
  13.         执行:save_boot_params,没实现,为空
  14.         关中断,设置SVC32模式
  15.         设置中断向量########,启用向量(CP15 VBAR register, @Set VBAR)
  16.         如果有的话就执行两个lowlevel_init,没有就跳过
  17.                 cpu_init_cp15
  18.                         除能L1 I/D cache,除能L2 cache,关闭mmu,cache
  19. cpu_init_crit
  20.         执行板级lowlevel_init,若定义靠外部实现,没有跳过
  21.         跳入主程序 _main########
  22. 设置一个全局变量gloader_tag
  23. arch/arm/lib/vectors.S:
  24. 设置全局变量:
  25. .globl _vector
  26. .globl RSA_KEY_TAG
  27. .globl RSA_KEY_LENGTH
  28. .globl RSA_KEY_DATA
  29. .globl LoaderTagCheck
  30. 设置中断向量:
  31. b        reset
  32. ldr        pc, _undefined_instruction
  33. ldr        pc, _software_interrupt
  34. ldr        pc, _prefetch_abort
  35. ldr        pc, _data_abort
  36. ldr        pc, _not_used
  37. ldr        pc, _irq
  38. ldr        pc, _fiq
  39.         如果不使用 SPL,就把中断处理实现了,使用 SPL 的话很可能在之后的代码实现。
  40.         这个文件是汇编,一堆宏实现的中断处理
  41. arch/arm/lib/crt0.S: _main
  42.         初始化C runtime environment,
  43.                 设置CONFIG_SYS_INIT_SP_ADDR
  44. (=CONFIG_RAM_PHY_END , include/configs/rk_default_config.h)
  45.         (=0x0+SZ_128M , include/configs/rk32plat.h)
  46.                 (arm寄存器,r2=sp,r9=gd,r1=gd,r0=0)
  47.                 设置GD_SIZE
  48.                 初始化GD空间
  49.         执行board_init_f########
  50.         重设置 sp,gd
  51.         执行relocate_code
  52.         初始化final environment
  53. 执行c_runtime_cpu_setup:开机ICACHE,DCACHE,设置_vector/_start
  54. 预留bss空间并清零
  55.         执行coloured_LED_init  (板级实现,有没有无所谓)
  56. 执行red_led_on  (板级实现,有没有无所谓)
  57.         执行 board_init_r########  (这个是个函数数组,一堆函数)
  58. common/board_f.c:board_init_f
  59.         (初始化GD空间)
  60.         调用initcall_run_list()
  61.                 执行init_sequence_f
  62. setup_ram_buf:设置gd->ram_size 和 gd->arch.ram_buf
  63. setup_mon_len:设置gd->mon_len
  64. setup_fdt:设置gd->fdt_blob
  65. trace_early_init:(ifdef CONFIG_TRACE) trace memory map
  66. initf_malloc:初始化malloc,设置gd->malloc_limit,清零gd->malloc_ptr
  67. arch_cpu_init:空,啥也没干
  68. mark_bootstage:做个标记
  69. fdtdec_check_fdt:(ifdef CONFIG_OF_CONTROL)调用fdtdec_prepare_fdt,检查gd->fdt_blob 有效性
  70. initf_dm:分4步dm_init,dm_scan_platdata,dm_scan_fdt,dm_scan_other
  71.         dm_init:gd->dm_root 存在就退出,不存在分三步执行:
  72. 初始化链表INIT_LIST_HEAD
  73. device_bind_by_name:最终执行 device_bind
  74. device_probe:uclass_post_probe_device
  75.                                 dm_scan_platdata:扫描链表实现
  76.         dm_scan_fdt:扫描链表
  77.         dm_scan_other:空,啥也没有
  78. board_early_init_f:(if defined(CONFIG_BOARD_EARLY_INIT_F)
  79.         空,没有实现
  80. timer_init:没有实现。Armv7通用代码初始化下面三个成员变量
  81. gd->arch.tbl=0;
  82. gd->arch.tbu = 0;
  83. gd->arch.timer_rate_hz = CONFIG_SYS_HZ_CLOCK / CONFIG_SYS_HZ
  84. env_init:没有实现,通用代码初始化两个成员变量
  85. gd->env_addr= (ulong)&default_environment[0];
  86. gd->env_valid        = 1
  87. init_baud_rate:初始化成员变量baudrate
  88.         gd->baudrate = getenv_ulong("baudrate", 10, CONFIG_BAUDRATE);
  89. serial_init:获取驱动结构体,设置gd->flag
  90.         gd->flags |= GD_FLG_SERIAL_READY;
  91.         return get_current()->start();
  92. console_init_f:设置控制台标志,设置gd->flag
  93.         gd->have_console = 1;
  94. gd->flags |= GD_FLG_SILENT;(ifdef CONFIG_SILENT_CONSOLE)
  95. fdtdec_prepare_fdt:检查fdt状态(gd->fdt_blob)
  96. display_options:打印uboot版本信息,build时间
  97. printf ("\n\n%s, Build: %s\n\n", version_string, BUILD_TAG);
  98. printf ("\n\n%s\n\n", version_string);
  99. display_text_info:打印内存代码段地址,bss段地址,打印IRQ,FIQ栈地址
  100. print_cpuinfo:没实现。其他板子是打印cpu信息
  101. show_board_info
  102. 调用board/rockchip/rk32xx/rk32xx.c:checkboard函数,打印:
  103. puts("Board:\tRockchip platform Board\n");
  104. INIT_FUNC_WATCHDOG_INIT:宏定义一个函数入口,如果有实现以下
  105. 打印puts("Watchdog enabled\n");并且初始化WATCHDOG_RESET
  106. misc_init_f:(if defined(CONFIG_MISC_INIT_F)),没实现
  107. INIT_FUNC_WATCHDOG_RESET:还是调用WATCHDOG_RESET
  108. init_func_i2c:rk专用文件drivers/i2c/rk_i2c.c
  109. 打印i2c_info("i2c_init\n");
  110. 设置 iomux,设置clk
  111. init_func_spi:rk实现为空
  112.         打印SPI:ready,什么也不做
  113.                         announce_dram_init:打印信息
  114.                                 puts("DRAM:  ");
  115.                         dram_init:初始化dram(/* configure available RAM banks */)
  116. rk没有实现,是因为rk提供bin文件,在开头loadertag 里面有代码
  117.                         INIT_FUNC_WATCHDOG_RESET:又一次reset
  118. Uboot 启用watchdog,是最最基础的功能,后续还有很多这个代码
  119.                         Testdram:这个是空,如果if defined(CONFIG_SYS_DRAM_TEST)才执行
  120.                         INIT_FUNC_WATCHDOG_RESET:
  121.                         init_post:如果ifdef CONFIG_POST才执行
  122.                         INIT_FUNC_WATCHDOG_RESET:
  123.                         setup_dest_addr:
  124.                         reserve_uboot:计算gd->relocaddr,预留空间,对齐,打印信息
  125.                         reserve_logbuffer:计算gd->relocaddr,预留空间,对齐,打印信息
  126.                         reserve_pram:计算gd->relocaddr,预留空间,对齐,打印信息
  127.                         reserve_round_4k:计算gd->relocaddr,4KB对齐
  128.                         reserve_mmu:计算gd->relocaddr,赋值gd->arch.tlb_size,对齐打印
  129.                                 gd->arch.tlb_size = PGTABLE_SIZE;
  130.                         reserve_lcd:计算gd->relocaddr,赋值gd->fb_base,对齐打印
  131. 调用lcd_setmem(common/lcd.c),获取预留之后的gd->relocaddr更新
  132. 并赋值给gd->fb_base
  133.                         reserve_global_buffers:预留四个buffer:
  134.                                 gd->arch.rk_global_buf_addr:
  135.                                 gd->arch.rk_boot_buf_addr:
  136.                                 gd->arch.fastboot_buf_addr:fastboot 和 boot 使用同样空间
  137.                                 gd->arch.fastboot_log_buf_addr:
  138.                         reserve_trace:预留,赋值gd->trace_buff,打印
  139.                         reserve_video:其他架构使用,预留fb,赋值gd->fb_base
  140.                         reserve_uboot:跟前面实现同样功能,只是内存位置分配不同
  141.                         reserve_malloc:预留malloc()空间,从gd->start_addr_sp顶部预留
  142.                         reserve_board:预留gd->bd空间,从gd->start_addr_sp顶部预留,
  143.                                 赋值gd->bd为gd->bd空间底部,并打印信息
  144.                         setup_machine:赋值gd->bd->bi_arch_number,注释说明了一切
  145. gd->bd->bi_arch_number = CONFIG_MACH_TYPE;
  146. /* board id for Linux */
  147.                         reserve_global_data:设置新的gd->new_gd,并打印
  148.                         reserve_fdt:
  149.                                 从栈空间gd->start_addr_sp预留一个gd->fdt_blob,并赋值gd->new_fdt
  150.                         reserve_stacks:设置栈指针,并对齐(16Byte对齐)
  151.                                 gd->start_addr_sp:
  152.                         setup_dram_config:调用dram_init_banksize,设置成员变量
  153.                                 赋值gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE
  154.                                 赋值gd->bd->bi_dram[0].size
  155.                         show_dram_config:打印信息
  156.                                 Bank 1: 0x00000000
  157. Bank 2: 0x08000000
  158. ………….
  159.                         display_new_sp:打印新sp
  160.                         setup_board_extra:如果ifdef CONFIG_SYS_EXTBDINFO设置gd->bd变量
  161.                                 bd->bi_s_version = “1.2”
  162.                                 bd->bi_r_version = "U-Boot 2014.10-RK3288-10"
  163.                                 bd->bi_procfreq = gd->cpu_clk
  164.                                 bd->bi_plb_busfreq = gd->bus_clk;
  165.                         INIT_FUNC_WATCHDOG_RESET
  166.                         reloc_fdt:memcpy() 实现,从gd->fdt_blob 复制到gd->new_fdt
  167. setup_reloc
  168. gd->reloc_off = gd->relocaddr - CONFIG_SYS_TEXT_BASE;
  169. memcpy(gd->new_gd, (char *)gd, sizeof(gd_t));
  170.                         NULL:结束了,这个NULL必须要,退出项
  171. common/board_r.c:board_init_r########
  172.         调用initcall_run_list()
  173.                 initr_trace:初始化hdr空间,赋值gd->trace_buff
  174.                         hdr->func_count
  175.                         hdr->call_accum
  176.                         hdr->ftrace
  177.                         hdr->ftrace_size
  178.                         hdr->depth_limit
  179.                 initr_reloc:
  180.                         gd->flags |= GD_FLG_RELOC
  181.                         bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_R, "board_init_r")
  182.                 initr_caches:没有实现,为空
  183.                 initr_barrier:为空,ppc专用
  184.                 initr_malloc:从gd->relocaddr往下分配malloc空间,并初始化
  185.                         malloc_start = gd->relocaddr - TOTAL_MALLOC_LEN;
  186.                 bootstage_relocate:填充record[xxx].name 变量,使用 memcpy实现
  187.                 initr_dm:保存gd->dm_root_f,置零gd->dm_root,重新调用dm_init_and_scan
  188. gd->dm_root_f = gd->dm_root;
  189.                         gd->dm_root = NULL;
  190.                         dm_init_and_scan,同上
  191.                 board_init:rk3288没有实现,为空
  192.                 set_cpu_clk_info:设置gd->bd 三个结构体
  193.                         gd->bd->bi_arm_freq
  194.                         gd->bd->bi_dsp_freq
  195. gd->bd->bi_ddr_freq
  196.                 stdio_init_tables:
  197.                         重新建立stdio_names,初始化devs.list 链表头,
  198.                 initr_serial:
  199.                         从fdt中找出chosen节点,alias节点,
  200.                         找出UCLASS_SERIAL节点,放入cur_dev 指针中(udevice 结构体)
  201.                         查找是否设备列表是否有这个节点,没有的话 device_probe
  202.                         打印信息
  203.                 initr_announce:
  204. 打印信息Now running in RAM - U-Boot at: %08lx\n", gd->relocaddr
  205. 或者Now running in RAM - U-Boot at: %08lx\n", CONFIG_SYS_TEXT_BASE
  206.                 INIT_FUNC_WATCHDOG_RESET:看门狗同上
  207.                 initr_addr_map:没有实现,为空
  208.                 board_early_init_r:没有实现,为空
  209.                 board_early_init_r
  210.                 INIT_FUNC_WATCHDOG_RESET
  211.                 initr_logbuffer:
  212.                         设置console_loglevel,设置log_version,初始化log 结构体
  213.                 initr_post_backlog:没有实现
  214.                 INIT_FUNC_WATCHDOG_RESET
  215.                 initr_icache_enable:
  216.                 initr_icache_enable:
  217.                 power_init_board:
  218. power_init_board:
  219. INIT_FUNC_WATCHDOG_RESET:
  220. initr_nand:
  221. initr_onenand,:
  222. initr_mmc:
  223. initr_dataflash,:
  224. initr_rk_storage,:rockchip 独有,如果ifdef CONFIG_ROCKCHIP
  225. initr_env:
  226. INIT_FUNC_WATCHDOG_RESET:
  227. initr_secondary_cpu:
  228. INIT_FUNC_WATCHDOG_RESET:
  229. stdio_add_devices,
  230. initr_jumptable,
  231. initr_api:
  232. console_init_r:/* fully init console as a device */
  233. show_board_info:
  234. arch_misc_init:
  235. misc_init_r:
  236. initr_hermes_start,:
  237. INIT_FUNC_WATCHDOG_RESET
  238. initr_kgdb,
  239. interrupt_init,
  240. initr_enable_interrupts,
  241. initr_status_led:初始化,点灯,和plat-xxxx架构相似的驱动结构
  242. initr_ethaddr,
  243. board_late_init:设置bootdelay,bootcmd,保存env
  244.         board_init_adjust_env:
  245.         load_disk_partitions
  246.         rkimage_prepare_fdt
  247.         pmic_init
  248.         pwm_regulator_init
  249.         fg_init
  250.         dram_freq_init
  251.         spk_io_init
  252.         rkidb_setup_space
  253.         rkidb_get_idblk_data
  254.         SecureBootCheck
  255.         rkidb_get_bootloader_ver
  256.         rkidb_get_sn(tmp_buf)
  257.         board_fbt_preboot
  258. initr_scsi
  259. initr_doc
  260. initr_bbmii
  261. initr_net
  262. initr_post
  263. initr_pcmcia
  264. initr_ide
  265. last_stage_init
  266. initr_bedbug
  267. initr_mem
  268. initr_kbd
  269. run_main_loop
  270.                         最后一个函数run_main_loop()调用了 main_loop()########
  271. Common/main.c:main_loop
  272.         bootstage_mark_name:
  273.         modem_init:空
  274.         setenv("ver", version_string);
  275.         cli_init:
  276.         run_preboot_environment_command:
  277.         update_tftp:
  278.         bootdelay_process:
  279.         cli_process_fdt:
  280. cli_secure_boot_cmd:
  281. autoboot_command:########
  282. cli_loop:不会执行到这里
  283. common/autoboot.c:autoboot_command【bootcmd】
  284.         debug("### main_loop: bootcmd="%s"\n", s ? s : "<UNDEFINED>");
  285.         disable_ctrlc:
  286. run_command_list:########
  287. disable_ctrlc:

  288. common/cli.c:run_command_list:
  289.         cli_simple_run_command_list:
  290.                 调用cli_simple_run_command:在common/cli_simple.c
  291.                         fdfdfdfdfdfdfd
  292.         




  293.         cli_simple_run_command:执行每一条CMD命令

  294. 最终是do_bootrk 引导进入内核:
  295.         puts("bootrk: do_bootm_linux...\n");
  296.         do_bootm_linux(0, 0, NULL, &images);
  297. 熟悉的不能再熟悉了
  298. do_bootm_linux:
  299.         调用boot_jump_linux
  300.                 kernel_entry(0, machid, r2);

  301. uboot结构体:bd (arch/arm/include/asm/u-boot.h) gd (include/asm-generic/global_data.h)
  302. 结构体1:gd
  303. typedef struct global_data {
  304.         bd_t *bd;
  305.         unsigned long flags;
  306.         unsigned int baudrate;
  307.         unsigned long cpu_clk;        /* CPU clock in Hz!                */
  308. #ifdef CONFIG_ROCKCHIP
  309.         unsigned long cpul_clk;        /* CPU clock in Hz!                */
  310. #endif
  311.         unsigned long bus_clk;
  312.         /* We cannot bracket this with CONFIG_PCI due to mpc5xxx */
  313.         unsigned long pci_clk;
  314.         unsigned long mem_clk;
  315. #if defined(CONFIG_LCD) || defined(CONFIG_VIDEO)
  316.         unsigned long fb_base;        /* Base address of framebuffer mem */
  317. #endif
  318. #if defined(CONFIG_POST) || defined(CONFIG_LOGBUFFER)
  319.         unsigned long post_log_word;  /* Record POST activities */
  320.         unsigned long post_log_res; /* success of POST test */
  321.         unsigned long post_init_f_time;  /* When post_init_f started */
  322. #endif
  323. #ifdef CONFIG_BOARD_TYPES
  324.         unsigned long board_type;
  325. #endif
  326.         unsigned long have_console;        /* serial_init() was called */
  327. #ifdef CONFIG_PRE_CONSOLE_BUFFER
  328.         unsigned long precon_buf_idx;        /* Pre-Console buffer index */
  329. #endif
  330. #ifdef CONFIG_MODEM_SUPPORT
  331.         unsigned long do_mdm_init;
  332.         unsigned long be_quiet;
  333. #endif
  334.         unsigned long env_addr;        /* Address  of Environment struct */
  335.         unsigned long env_valid;        /* Checksum of Environment valid? */

  336.         unsigned long ram_top;        /* Top address of RAM used by U-Boot */

  337.         unsigned long relocaddr;        /* Start address of U-Boot in RAM */
  338.         phys_size_t ram_size;        /* RAM size */
  339.         unsigned long mon_len;        /* monitor len */
  340.         unsigned long irq_sp;                /* irq stack pointer */
  341.         unsigned long start_addr_sp;        /* start_addr_stackpointer */
  342.         unsigned long reloc_off;
  343.         struct global_data *new_gd;        /* relocated global data */

  344. #ifdef CONFIG_DM
  345.         struct udevice        *dm_root;        /* Root instance for Driver Model */
  346.         struct udevice        *dm_root_f;        /* Pre-relocation root instance */
  347.         struct list_head uclass_root;        /* Head of core tree */
  348. #endif

  349.         const void *fdt_blob;        /* Our device tree, NULL if none */
  350.         void *new_fdt;                /* Relocated FDT */
  351.         unsigned long fdt_size;        /* Space reserved for relocated FDT */
  352.         void **jt;                /* jump table */
  353.         char env_buf[32];        /* buffer for getenv() before reloc. */
  354. #ifdef CONFIG_TRACE
  355.         void                *trace_buff;        /* The trace buffer */
  356. #endif
  357. #if defined(CONFIG_SYS_I2C)
  358.         int                cur_i2c_bus;        /* current used i2c bus */
  359. #endif
  360. #ifdef CONFIG_SYS_I2C_MXC
  361.         void *srdata[10];
  362. #endif
  363.         unsigned long timebase_h;
  364.         unsigned long timebase_l;
  365. #ifdef CONFIG_SYS_MALLOC_F_LEN
  366.         unsigned long malloc_base;        /* base address of early malloc() */
  367.         unsigned long malloc_limit;        /* limit address */
  368.         unsigned long malloc_ptr;        /* current address */
  369. #endif
  370.         struct arch_global_data arch;        /* architecture-specific data */
  371. } gd_t;
  372. 结构体2:bd
  373. typedef struct bd_info {
  374.     ulong                bi_arch_number;        /* unique id for this board */
  375.     ulong                bi_boot_params;        /* where this board expects params */
  376.         unsigned long        bi_arm_freq; /* arm frequency */
  377.         unsigned long        bi_dsp_freq; /* dsp core frequency */
  378.         unsigned long        bi_ddr_freq; /* ddr frequency */
  379.     struct                                /* RAM configuration */
  380.     {
  381.         ulong start;
  382.         ulong size;
  383.     }                        bi_dram[CONFIG_NR_DRAM_BANKS];

  384. #ifdef CONFIG_RK_MAX_DRAM_BANKS
  385.     struct                    /* RAM configuration for kernel */
  386.     {
  387.         u64 start;
  388.         u64 size;
  389.     }                         rk_dram[CONFIG_RK_MAX_DRAM_BANKS + 1];
  390. #endif /* CONFIG_RK_MAX_DRAM_BANKS */

  391. } bd_t;
  392. 结构体3:trace_hdr:/lib/trace.c
  393. struct trace_hdr {
  394.         int func_count;                /* Total number of function call sites */
  395.         u64 call_count;                /* Total number of tracked function calls */
  396.         u64 untracked_count;        /* Total number of untracked function calls */
  397.         int funcs_used;                /* Total number of functions used */

  398.         /*
  399.          * Call count for each function. This is indexed by the word offset
  400.          * of the function from gd->relocaddr
  401.          */
  402.         uintptr_t *call_accum;

  403.         /* Function trace list */
  404.         struct trace_call *ftrace;        /* The function call records */
  405.         ulong ftrace_size;        /* Num. of ftrace records we have space for */
  406.         ulong ftrace_count;        /* Num. of ftrace records written */
  407.         ulong ftrace_too_deep_count;        /* Functions that were too deep */

  408.         int depth;
  409.         int depth_limit;
  410.         int max_depth;
  411. };
  412. 结构体4:stdio_dev
  413. struct stdio_dev {
  414.         int        flags;                        /* Device flags: input/output/system        */
  415.         int        ext;                        /* Supported extensions                        */
  416.         char        name[16];                /* Device name                                */

  417. /* GENERAL functions */

  418.         int (*start)(struct stdio_dev *dev);        /* To start the device */
  419.         int (*stop)(struct stdio_dev *dev);        /* To stop the device */

  420. /* OUTPUT functions */

  421.         /* To put a char */
  422.         void (*putc)(struct stdio_dev *dev, const char c);
  423.         /* To put a string (accelerator) */
  424.         void (*puts)(struct stdio_dev *dev, const char *s);

  425. /* INPUT functions */

  426.         /* To test if a char is ready... */
  427.         int (*tstc)(struct stdio_dev *dev);
  428.         int (*getc)(struct stdio_dev *dev);        /* To get that char */

  429. /* Other functions */

  430.         void *priv;                        /* Private extensions                        */
  431.         struct list_head list;
  432. };
  433. 结构体5:udevice
  434. struct udevice {
  435.         struct driver *driver;
  436.         const char *name;
  437.         void *platdata;
  438.         int of_offset;
  439.         struct udevice *parent;
  440.         void *priv;
  441.         struct uclass *uclass;
  442.         void *uclass_priv;
  443.         void *parent_priv;
  444.         struct list_head uclass_node;
  445.         struct list_head child_head;
  446.         struct list_head sibling_node;
  447.         uint32_t flags;
  448.         int req_seq;
  449.         int seq;
  450. };
复制代码


关注下面的标签,发现更多相似文章
分享到:
回复

使用道具 举报

回答|共 2 个

倒序浏览

沙发

风之山谷

发表于 2018-7-19 09:34:57 | 只看该作者

膜拜大佬,都在看源码了
板凳

xiaoshen-372360

发表于 2018-8-30 17:22:55 | 只看该作者

学习了!!!!!!!膜拜膜拜
您需要登录后才可以回帖 注册/登录

本版积分规则

光学研发
14800 积分
320 主题
+ 关注
关闭

站长推荐上一条 /3 下一条