TA的每日心情 | 开心 昨天 22:46 |
---|
签到天数: 596 天 连续签到: 3 天 [LV.9]以坛为家II
|
本帖最后由 robe.zhang 于 2018-7-19 01:10 编辑
【DLT-RK3288试用】11,uboot源码分析
看了一遍源码看完了,重点看了启动失败的一部分;
rk3288 有一堆板级文件,是 rockchip 专有的,就是一些img有关存储有关的东西,也没有合入主线;
看了时候做了个记录,以下:
- arch/arm/cpu/armv7/start.S:
- 全局变量:
- Reset
- Rockchip 芯片在开头设置了loader_tag,确认通过的话才能运行,不然死到这里
- #ifdef CONFIG_ROCKCHIP
- ldr r0, =__loader_tag
- ldr r1, [r0]
- ldr r0, =LoaderTagCheck
- ldr r0, [r0]
- cmp r1, r0
- movne pc, r14
- #endif
- 执行:save_boot_params,没实现,为空
- 关中断,设置SVC32模式
- 设置中断向量########,启用向量(CP15 VBAR register, @Set VBAR)
- 如果有的话就执行两个lowlevel_init,没有就跳过
- cpu_init_cp15
- 除能L1 I/D cache,除能L2 cache,关闭mmu,cache
- cpu_init_crit
- 执行板级lowlevel_init,若定义靠外部实现,没有跳过
- 跳入主程序 _main########
- 设置一个全局变量gloader_tag
- arch/arm/lib/vectors.S:
- 设置全局变量:
- .globl _vector
- .globl RSA_KEY_TAG
- .globl RSA_KEY_LENGTH
- .globl RSA_KEY_DATA
- .globl LoaderTagCheck
- 设置中断向量:
- b reset
- ldr pc, _undefined_instruction
- ldr pc, _software_interrupt
- ldr pc, _prefetch_abort
- ldr pc, _data_abort
- ldr pc, _not_used
- ldr pc, _irq
- ldr pc, _fiq
- 如果不使用 SPL,就把中断处理实现了,使用 SPL 的话很可能在之后的代码实现。
- 这个文件是汇编,一堆宏实现的中断处理
- arch/arm/lib/crt0.S: _main
- 初始化C runtime environment,
- 设置CONFIG_SYS_INIT_SP_ADDR
- (=CONFIG_RAM_PHY_END , include/configs/rk_default_config.h)
- (=0x0+SZ_128M , include/configs/rk32plat.h)
- (arm寄存器,r2=sp,r9=gd,r1=gd,r0=0)
- 设置GD_SIZE
- 初始化GD空间
- 执行board_init_f########
- 重设置 sp,gd
- 执行relocate_code
- 初始化final environment
- 执行c_runtime_cpu_setup:开机ICACHE,DCACHE,设置_vector/_start
- 预留bss空间并清零
- 执行coloured_LED_init (板级实现,有没有无所谓)
- 执行red_led_on (板级实现,有没有无所谓)
- 执行 board_init_r######## (这个是个函数数组,一堆函数)
- common/board_f.c:board_init_f
- (初始化GD空间)
- 调用initcall_run_list()
- 执行init_sequence_f
- setup_ram_buf:设置gd->ram_size 和 gd->arch.ram_buf
- setup_mon_len:设置gd->mon_len
- setup_fdt:设置gd->fdt_blob
- trace_early_init:(ifdef CONFIG_TRACE) trace memory map
- initf_malloc:初始化malloc,设置gd->malloc_limit,清零gd->malloc_ptr
- arch_cpu_init:空,啥也没干
- mark_bootstage:做个标记
- fdtdec_check_fdt:(ifdef CONFIG_OF_CONTROL)调用fdtdec_prepare_fdt,检查gd->fdt_blob 有效性
- initf_dm:分4步dm_init,dm_scan_platdata,dm_scan_fdt,dm_scan_other
- dm_init:gd->dm_root 存在就退出,不存在分三步执行:
- 初始化链表INIT_LIST_HEAD
- device_bind_by_name:最终执行 device_bind
- device_probe:uclass_post_probe_device
- dm_scan_platdata:扫描链表实现
- dm_scan_fdt:扫描链表
- dm_scan_other:空,啥也没有
- board_early_init_f:(if defined(CONFIG_BOARD_EARLY_INIT_F)
- 空,没有实现
- timer_init:没有实现。Armv7通用代码初始化下面三个成员变量
- gd->arch.tbl=0;
- gd->arch.tbu = 0;
- gd->arch.timer_rate_hz = CONFIG_SYS_HZ_CLOCK / CONFIG_SYS_HZ
- env_init:没有实现,通用代码初始化两个成员变量
- gd->env_addr= (ulong)&default_environment[0];
- gd->env_valid = 1
- init_baud_rate:初始化成员变量baudrate
- gd->baudrate = getenv_ulong("baudrate", 10, CONFIG_BAUDRATE);
- serial_init:获取驱动结构体,设置gd->flag
- gd->flags |= GD_FLG_SERIAL_READY;
- return get_current()->start();
- console_init_f:设置控制台标志,设置gd->flag
- gd->have_console = 1;
- gd->flags |= GD_FLG_SILENT;(ifdef CONFIG_SILENT_CONSOLE)
- fdtdec_prepare_fdt:检查fdt状态(gd->fdt_blob)
- display_options:打印uboot版本信息,build时间
- printf ("\n\n%s, Build: %s\n\n", version_string, BUILD_TAG);
- printf ("\n\n%s\n\n", version_string);
- display_text_info:打印内存代码段地址,bss段地址,打印IRQ,FIQ栈地址
- print_cpuinfo:没实现。其他板子是打印cpu信息
- show_board_info
- 调用board/rockchip/rk32xx/rk32xx.c:checkboard函数,打印:
- puts("Board:\tRockchip platform Board\n");
- INIT_FUNC_WATCHDOG_INIT:宏定义一个函数入口,如果有实现以下
- 打印puts("Watchdog enabled\n");并且初始化WATCHDOG_RESET
- misc_init_f:(if defined(CONFIG_MISC_INIT_F)),没实现
- INIT_FUNC_WATCHDOG_RESET:还是调用WATCHDOG_RESET
- init_func_i2c:rk专用文件drivers/i2c/rk_i2c.c
- 打印i2c_info("i2c_init\n");
- 设置 iomux,设置clk
- init_func_spi:rk实现为空
- 打印SPI:ready,什么也不做
- announce_dram_init:打印信息
- puts("DRAM: ");
- dram_init:初始化dram(/* configure available RAM banks */)
- rk没有实现,是因为rk提供bin文件,在开头loadertag 里面有代码
- INIT_FUNC_WATCHDOG_RESET:又一次reset
- Uboot 启用watchdog,是最最基础的功能,后续还有很多这个代码
- Testdram:这个是空,如果if defined(CONFIG_SYS_DRAM_TEST)才执行
- INIT_FUNC_WATCHDOG_RESET:
- init_post:如果ifdef CONFIG_POST才执行
- INIT_FUNC_WATCHDOG_RESET:
- setup_dest_addr:
- reserve_uboot:计算gd->relocaddr,预留空间,对齐,打印信息
- reserve_logbuffer:计算gd->relocaddr,预留空间,对齐,打印信息
- reserve_pram:计算gd->relocaddr,预留空间,对齐,打印信息
- reserve_round_4k:计算gd->relocaddr,4KB对齐
- reserve_mmu:计算gd->relocaddr,赋值gd->arch.tlb_size,对齐打印
- gd->arch.tlb_size = PGTABLE_SIZE;
- reserve_lcd:计算gd->relocaddr,赋值gd->fb_base,对齐打印
- 调用lcd_setmem(common/lcd.c),获取预留之后的gd->relocaddr更新
- 并赋值给gd->fb_base
- reserve_global_buffers:预留四个buffer:
- gd->arch.rk_global_buf_addr:
- gd->arch.rk_boot_buf_addr:
- gd->arch.fastboot_buf_addr:fastboot 和 boot 使用同样空间
- gd->arch.fastboot_log_buf_addr:
- reserve_trace:预留,赋值gd->trace_buff,打印
- reserve_video:其他架构使用,预留fb,赋值gd->fb_base
- reserve_uboot:跟前面实现同样功能,只是内存位置分配不同
- reserve_malloc:预留malloc()空间,从gd->start_addr_sp顶部预留
- reserve_board:预留gd->bd空间,从gd->start_addr_sp顶部预留,
- 赋值gd->bd为gd->bd空间底部,并打印信息
- setup_machine:赋值gd->bd->bi_arch_number,注释说明了一切
- gd->bd->bi_arch_number = CONFIG_MACH_TYPE;
- /* board id for Linux */
- reserve_global_data:设置新的gd->new_gd,并打印
- reserve_fdt:
- 从栈空间gd->start_addr_sp预留一个gd->fdt_blob,并赋值gd->new_fdt
- reserve_stacks:设置栈指针,并对齐(16Byte对齐)
- gd->start_addr_sp:
- setup_dram_config:调用dram_init_banksize,设置成员变量
- 赋值gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE
- 赋值gd->bd->bi_dram[0].size
- show_dram_config:打印信息
- Bank 1: 0x00000000
- Bank 2: 0x08000000
- ………….
- display_new_sp:打印新sp
- setup_board_extra:如果ifdef CONFIG_SYS_EXTBDINFO设置gd->bd变量
- bd->bi_s_version = “1.2”
- bd->bi_r_version = "U-Boot 2014.10-RK3288-10"
- bd->bi_procfreq = gd->cpu_clk
- bd->bi_plb_busfreq = gd->bus_clk;
- INIT_FUNC_WATCHDOG_RESET
- reloc_fdt:memcpy() 实现,从gd->fdt_blob 复制到gd->new_fdt
- setup_reloc
- gd->reloc_off = gd->relocaddr - CONFIG_SYS_TEXT_BASE;
- memcpy(gd->new_gd, (char *)gd, sizeof(gd_t));
- NULL:结束了,这个NULL必须要,退出项
- common/board_r.c:board_init_r########
- 调用initcall_run_list()
- initr_trace:初始化hdr空间,赋值gd->trace_buff
- hdr->func_count
- hdr->call_accum
- hdr->ftrace
- hdr->ftrace_size
- hdr->depth_limit
- initr_reloc:
- gd->flags |= GD_FLG_RELOC
- bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_R, "board_init_r")
- initr_caches:没有实现,为空
- initr_barrier:为空,ppc专用
- initr_malloc:从gd->relocaddr往下分配malloc空间,并初始化
- malloc_start = gd->relocaddr - TOTAL_MALLOC_LEN;
- bootstage_relocate:填充record[xxx].name 变量,使用 memcpy实现
- initr_dm:保存gd->dm_root_f,置零gd->dm_root,重新调用dm_init_and_scan
- gd->dm_root_f = gd->dm_root;
- gd->dm_root = NULL;
- dm_init_and_scan,同上
- board_init:rk3288没有实现,为空
- set_cpu_clk_info:设置gd->bd 三个结构体
- gd->bd->bi_arm_freq
- gd->bd->bi_dsp_freq
- gd->bd->bi_ddr_freq
- stdio_init_tables:
- 重新建立stdio_names,初始化devs.list 链表头,
- initr_serial:
- 从fdt中找出chosen节点,alias节点,
- 找出UCLASS_SERIAL节点,放入cur_dev 指针中(udevice 结构体)
- 查找是否设备列表是否有这个节点,没有的话 device_probe
- 打印信息
- initr_announce:
- 打印信息Now running in RAM - U-Boot at: %08lx\n", gd->relocaddr
- 或者Now running in RAM - U-Boot at: %08lx\n", CONFIG_SYS_TEXT_BASE
- INIT_FUNC_WATCHDOG_RESET:看门狗同上
- initr_addr_map:没有实现,为空
- board_early_init_r:没有实现,为空
- board_early_init_r
- INIT_FUNC_WATCHDOG_RESET
- initr_logbuffer:
- 设置console_loglevel,设置log_version,初始化log 结构体
- initr_post_backlog:没有实现
- INIT_FUNC_WATCHDOG_RESET
- initr_icache_enable:
- initr_icache_enable:
- power_init_board:
- power_init_board:
- INIT_FUNC_WATCHDOG_RESET:
- initr_nand:
- initr_onenand,:
- initr_mmc:
- initr_dataflash,:
- initr_rk_storage,:rockchip 独有,如果ifdef CONFIG_ROCKCHIP
- initr_env:
- INIT_FUNC_WATCHDOG_RESET:
- initr_secondary_cpu:
- INIT_FUNC_WATCHDOG_RESET:
- stdio_add_devices,
- initr_jumptable,
- initr_api:
- console_init_r:/* fully init console as a device */
- show_board_info:
- arch_misc_init:
- misc_init_r:
- initr_hermes_start,:
- INIT_FUNC_WATCHDOG_RESET
- initr_kgdb,
- interrupt_init,
- initr_enable_interrupts,
- initr_status_led:初始化,点灯,和plat-xxxx架构相似的驱动结构
- initr_ethaddr,
- board_late_init:设置bootdelay,bootcmd,保存env
- board_init_adjust_env:
- load_disk_partitions
- rkimage_prepare_fdt
- pmic_init
- pwm_regulator_init
- fg_init
- dram_freq_init
- spk_io_init
- rkidb_setup_space
- rkidb_get_idblk_data
- SecureBootCheck
- rkidb_get_bootloader_ver
- rkidb_get_sn(tmp_buf)
- board_fbt_preboot
- initr_scsi
- initr_doc
- initr_bbmii
- initr_net
- initr_post
- initr_pcmcia
- initr_ide
- last_stage_init
- initr_bedbug
- initr_mem
- initr_kbd
- run_main_loop
- 最后一个函数run_main_loop()调用了 main_loop()########
- Common/main.c:main_loop
- bootstage_mark_name:
- modem_init:空
- setenv("ver", version_string);
- cli_init:
- run_preboot_environment_command:
- update_tftp:
- bootdelay_process:
- cli_process_fdt:
- cli_secure_boot_cmd:
- autoboot_command:########
- cli_loop:不会执行到这里
- common/autoboot.c:autoboot_command【bootcmd】
- debug("### main_loop: bootcmd="%s"\n", s ? s : "<UNDEFINED>");
- disable_ctrlc:
- run_command_list:########
- disable_ctrlc:
- common/cli.c:run_command_list:
- cli_simple_run_command_list:
- 调用cli_simple_run_command:在common/cli_simple.c
- fdfdfdfdfdfdfd
-
- cli_simple_run_command:执行每一条CMD命令
- 最终是do_bootrk 引导进入内核:
- puts("bootrk: do_bootm_linux...\n");
- do_bootm_linux(0, 0, NULL, &images);
- 熟悉的不能再熟悉了
- do_bootm_linux:
- 调用boot_jump_linux
- kernel_entry(0, machid, r2);
- uboot结构体:bd (arch/arm/include/asm/u-boot.h) gd (include/asm-generic/global_data.h)
- 结构体1:gd
- typedef struct global_data {
- bd_t *bd;
- unsigned long flags;
- unsigned int baudrate;
- unsigned long cpu_clk; /* CPU clock in Hz! */
- #ifdef CONFIG_ROCKCHIP
- unsigned long cpul_clk; /* CPU clock in Hz! */
- #endif
- unsigned long bus_clk;
- /* We cannot bracket this with CONFIG_PCI due to mpc5xxx */
- unsigned long pci_clk;
- unsigned long mem_clk;
- #if defined(CONFIG_LCD) || defined(CONFIG_VIDEO)
- unsigned long fb_base; /* Base address of framebuffer mem */
- #endif
- #if defined(CONFIG_POST) || defined(CONFIG_LOGBUFFER)
- unsigned long post_log_word; /* Record POST activities */
- unsigned long post_log_res; /* success of POST test */
- unsigned long post_init_f_time; /* When post_init_f started */
- #endif
- #ifdef CONFIG_BOARD_TYPES
- unsigned long board_type;
- #endif
- unsigned long have_console; /* serial_init() was called */
- #ifdef CONFIG_PRE_CONSOLE_BUFFER
- unsigned long precon_buf_idx; /* Pre-Console buffer index */
- #endif
- #ifdef CONFIG_MODEM_SUPPORT
- unsigned long do_mdm_init;
- unsigned long be_quiet;
- #endif
- unsigned long env_addr; /* Address of Environment struct */
- unsigned long env_valid; /* Checksum of Environment valid? */
- unsigned long ram_top; /* Top address of RAM used by U-Boot */
- unsigned long relocaddr; /* Start address of U-Boot in RAM */
- phys_size_t ram_size; /* RAM size */
- unsigned long mon_len; /* monitor len */
- unsigned long irq_sp; /* irq stack pointer */
- unsigned long start_addr_sp; /* start_addr_stackpointer */
- unsigned long reloc_off;
- struct global_data *new_gd; /* relocated global data */
- #ifdef CONFIG_DM
- struct udevice *dm_root; /* Root instance for Driver Model */
- struct udevice *dm_root_f; /* Pre-relocation root instance */
- struct list_head uclass_root; /* Head of core tree */
- #endif
- const void *fdt_blob; /* Our device tree, NULL if none */
- void *new_fdt; /* Relocated FDT */
- unsigned long fdt_size; /* Space reserved for relocated FDT */
- void **jt; /* jump table */
- char env_buf[32]; /* buffer for getenv() before reloc. */
- #ifdef CONFIG_TRACE
- void *trace_buff; /* The trace buffer */
- #endif
- #if defined(CONFIG_SYS_I2C)
- int cur_i2c_bus; /* current used i2c bus */
- #endif
- #ifdef CONFIG_SYS_I2C_MXC
- void *srdata[10];
- #endif
- unsigned long timebase_h;
- unsigned long timebase_l;
- #ifdef CONFIG_SYS_MALLOC_F_LEN
- unsigned long malloc_base; /* base address of early malloc() */
- unsigned long malloc_limit; /* limit address */
- unsigned long malloc_ptr; /* current address */
- #endif
- struct arch_global_data arch; /* architecture-specific data */
- } gd_t;
- 结构体2:bd
- typedef struct bd_info {
- ulong bi_arch_number; /* unique id for this board */
- ulong bi_boot_params; /* where this board expects params */
- unsigned long bi_arm_freq; /* arm frequency */
- unsigned long bi_dsp_freq; /* dsp core frequency */
- unsigned long bi_ddr_freq; /* ddr frequency */
- struct /* RAM configuration */
- {
- ulong start;
- ulong size;
- } bi_dram[CONFIG_NR_DRAM_BANKS];
- #ifdef CONFIG_RK_MAX_DRAM_BANKS
- struct /* RAM configuration for kernel */
- {
- u64 start;
- u64 size;
- } rk_dram[CONFIG_RK_MAX_DRAM_BANKS + 1];
- #endif /* CONFIG_RK_MAX_DRAM_BANKS */
- } bd_t;
- 结构体3:trace_hdr:/lib/trace.c
- struct trace_hdr {
- int func_count; /* Total number of function call sites */
- u64 call_count; /* Total number of tracked function calls */
- u64 untracked_count; /* Total number of untracked function calls */
- int funcs_used; /* Total number of functions used */
- /*
- * Call count for each function. This is indexed by the word offset
- * of the function from gd->relocaddr
- */
- uintptr_t *call_accum;
- /* Function trace list */
- struct trace_call *ftrace; /* The function call records */
- ulong ftrace_size; /* Num. of ftrace records we have space for */
- ulong ftrace_count; /* Num. of ftrace records written */
- ulong ftrace_too_deep_count; /* Functions that were too deep */
- int depth;
- int depth_limit;
- int max_depth;
- };
- 结构体4:stdio_dev
- struct stdio_dev {
- int flags; /* Device flags: input/output/system */
- int ext; /* Supported extensions */
- char name[16]; /* Device name */
- /* GENERAL functions */
- int (*start)(struct stdio_dev *dev); /* To start the device */
- int (*stop)(struct stdio_dev *dev); /* To stop the device */
- /* OUTPUT functions */
- /* To put a char */
- void (*putc)(struct stdio_dev *dev, const char c);
- /* To put a string (accelerator) */
- void (*puts)(struct stdio_dev *dev, const char *s);
- /* INPUT functions */
- /* To test if a char is ready... */
- int (*tstc)(struct stdio_dev *dev);
- int (*getc)(struct stdio_dev *dev); /* To get that char */
- /* Other functions */
- void *priv; /* Private extensions */
- struct list_head list;
- };
- 结构体5:udevice
- struct udevice {
- struct driver *driver;
- const char *name;
- void *platdata;
- int of_offset;
- struct udevice *parent;
- void *priv;
- struct uclass *uclass;
- void *uclass_priv;
- void *parent_priv;
- struct list_head uclass_node;
- struct list_head child_head;
- struct list_head sibling_node;
- uint32_t flags;
- int req_seq;
- int seq;
- };
复制代码
|
|