OpenSBI简介-4

本文以OpenSBI 0.9版本为参考进行讲解

现在分析sbi_init源码,进入sbi_init时,scratch是唯一的参数。在进入sbi_init前,每个cpu会把_trap_handler的地址设置到mtvec里面。

  1. sbi_init函数
    void __noreturn sbi_init(struct sbi_scratch *scratch)
    {
    bool next_mode_supported = FALSE;
    bool coldboot = FALSE;
    u32 hartid = current_hartid();
    const struct sbi_platform *plat = sbi_platform_ptr(scratch);

     if ((SBI_HARTMASK_MAX_BITS <= hartid) ||  //hartid错误,超过了最大值,当前core 进入了wfi状态
     	sbi_platform_hart_invalid(plat, hartid))
     	sbi_hart_hang();
    
     switch (scratch->next_mode) {
     case PRV_M:
     	next_mode_supported = TRUE;
     	break;
     case PRV_S: /* 对于jump模式,会走这里 */
     	if (misa_extension('S'))  /* 查看当前模式是否支持 */
     		next_mode_supported = TRUE;
     	break;
     case PRV_U:
     	if (misa_extension('U'))
     		next_mode_supported = TRUE;
     	break;
     default:
     	sbi_hart_hang();
     }
    
     /*
      * Only the HART supporting privilege mode specified in the
      * scratch->next_mode should be allowed to become the coldboot
      * HART because the coldboot HART will be directly jumping to
      * the next booting stage.
      *
      * We use a lottery mechanism to select coldboot HART among
      * HARTs which satisfy above condition.
      */
    
     /* 
      * atomic_xchg作用就是原子操作,设置coldboot_lottery新值返回旧值,第一次设置,设置的是1,返回的是0,
      * 所以说第一个设置的core就是负责boot的core,那么执行的就是coldboot,其他的core执行是warmboot
      * 下面约定主core就是负责coldboot的core,其他的是从core,主core不一定是core 0
      */
     if (next_mode_supported && atomic_xchg(&coldboot_lottery, 1) == 0)
     	coldboot = TRUE;
    
     if (coldboot)
     	/* 全局数据的初始化由主core完成,coldboot初始化的会比warmboot多,sbi的打印默认是由主core输出的,从core没有log */
     	init_coldboot(scratch, hartid); 
     else
     	/* 从core会在sbi_hsm_init->sbi_hsm_hart_wait里面wfi,直到被下一级boot唤醒,从core只初始化自己独有的数据或者寄存器 */
     	init_warmboot(scratch, hartid); 
    

    }

  2. init_coldboot(scratch, hartid);
    static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)
    {
    int rc;
    unsigned long *init_count;
    const struct sbi_platform *plat = sbi_platform_ptr(scratch);

     /* Note: This has to be first thing in coldboot init sequence */
     /* 创建hartid_to_scratch_table映射表,也就是hart id和scrash内存绑定的表;记录last_hartid_having_scratch值,也就是core的最大值index(core count -1) */
     rc = sbi_scratch_init(scratch);  ------ 详见2.1
     if (rc)
     	sbi_hart_hang();
    
     /* Note: This has to be second thing in coldboot init sequence */
     /* 
      * 初始化动态加载的镜像的模块,并把mem region注册到hartid_to_domain_table数组里面。
      * 这里的mem region会在sbi_hart_pmp_configure中进行配置保护 
      * 这里注册了两个mem regions,一个是fw自己所占的内存,一个是任意的地址
      */
     rc = sbi_domain_init(scratch, hartid);
     if (rc)
     	sbi_hart_hang();
    
     /* 
      * 每一个hart id的scrash内存里面,从SBI_SCRATCH_EXTRA_SPACE_OFFSET这个地方偏移开始申请__SIZEOF_POINTER__大小的内存,并memset为0 
      * 从core也会判断init_count_offset是否正确,内存是否分配成功
      */
     init_count_offset = sbi_scratch_alloc_offset(__SIZEOF_POINTER__,  ---------------- 详见2.2
     						 "INIT_COUNT");
     if (!init_count_offset)
     	sbi_hart_hang();
    
     /* 
      *每一个core申请hart data内存,并把每一个core的state设置为SBI_HART_STARTING,这个函数主从core都会调用,
      * 主core申请内存设置状态,从core在wfi,直到自己的state设置为SBI_HART_STARTING
      * hsm应该是hart state mechine的简写。
      */
     rc = sbi_hsm_init(scratch, hartid, TRUE);  -------------------详见2.3
     if (rc)
     	sbi_hart_hang();
    
     /* 
      * 平台相关的早期的初始化,调用platform.c里面设置的回调函数:early_init,用户可以把需要初始化的
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值