高通平台BootLoader的流程

简谈高通Trustzone的实现 从trust zone之我见知道,支持trustzone的芯片会跑在两个世界。 普通世界、安全世界,对应高通这边是HLOS,QSEE。 如下图: 如下是HLOS与QSEE的软件架构图 HLOS这两分为kernel层,user层。user层的通过qseecom提供的API起动trustzone那边的app。 qseecom driver 除了提供AP 阅读详情

原文链接:http://www.codingblog.cn/blog/44451.html

注:很多内容和MTK  LK阶段相同,可以借鉴学习。aboot.c内容差异很大。

本文以C6的bootlader代码为例,

 

1. 一  kmain

1.1. 1 crt0.S

手机上电后,硬件会从固定的地址(固化在ROM中)加载bootloader到RAM,然后跳转到bootloader的入口函数开始执行,对于mido,它的入口函数是:

bootable/bootloader/lk/arch/arm/crt0.S  Collapse
source
#define
DSB .
byte  0x4f ,  0xf0 ,  0x7f ,  0xf5
#define
ISB .
byte  0x6f ,  0xf0 ,  0x7f ,  0xf5
.section  ".text.boot"
.globl
_start
_start:
     b  
reset
     b  
arm_undefined
     b  
arm_syscall
     b  
arm_prefetch_abort
 
.....
.....
.....
 
#ifdef
ARM_CPU_CORTEX_A8
     DSB
     ISB
#endif
     bl     
kmain
     b      
.

在_start中先主要完成CPU初始化,禁用mmu,禁用cache,初始化异常向量表等操作,最后将直接跳转到函数kmain中

1.2. 2 kmain

kmain的代码位于

bootable/bootloader/lk/kernel/main.c  Collapse
source
/*
called from crt0.S */
void  kmain( void )
__NO_RETURN __EXTERNALLY_VISIBLE;
void  kmain( void )
{
     //
get us into some sort of thread context
     thread_init_early();
     //
early arch stuff
     arch_early_init();
     //
do any super early platform initialization
     platform_early_init();
     //
do any super early target initialization
     target_early_init();
     dprintf(INFO,  "welcome
to lk\n\n"
);
     bs_set_timestamp(BS_BL_START);
     //
deal with any static constructors
     dprintf(SPEW,  "calling
constructors\n"
);
     call_constructors();
     //
bring up the kernel heap
     dprintf(SPEW,  "initializing
heap\n"
);
     heap_init();
     __stack_chk_guard_setup();
     //
initialize the threading system
     dprintf(SPEW,  "initializing
threads\n"
);
     thread_init();
     //
initialize the dpc system
     dprintf(SPEW,  "initializing
dpc\n"
);
     dpc_init();
     //
initialize kernel timers
     dprintf(SPEW,  "initializing
timers\n"
);
     timer_init();
#if
(!ENABLE_NANDWRITE)
     //
create a thread to complete system initialization
     dprintf(SPEW,  "creating
bootstrap completion thread\n"
);
     thread_resume(thread_create( "bootstrap2" ,
&bootstrap2, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE));
     //
enable interrupts
     exit_critical_section();
     //
become the idle thread
     thread_become_idle();
#else
         bootstrap_nandwrite();
#endif
}

在kmain中,

2.1 调用thread_init_early初始化线程系统

2.2 调用arch_early_init中判断如果存在mmu就初始化,设置异常向量基地址,使能中断相关寄存器

2.3 在platform_early_init中完成初始化硬件时钟、手机的主板等操作,这个函数每种cpu的实现都不一样,定义在bootable\bootloader\lk\platform\{cpu型号}\platform.c下

2.4 target_early_init中完成初始化uart端口的操作,这个函数的实现在bootable\bootloader\lk\target\{cpu型号}\init.c

2.5 首先输出调试信息”welcome to lk\n\n”,在bootable/bootloader/lk/include/debug.h中将INFO定义为了类似kernel中使用的debug
level,同时定义了dprintf

bootable/bootloader/lk/include/debug.h  Collapse
source
44 /*
debug levels */
45#define
CRITICAL 0
46#define
ALWAYS 0
47#define
INFO 1
48#define
SPEW 2
49
50 /*
output */
51void
_dputc(
char  c);  //
XXX for now, platform implements
52int
_dputs(
const  char  *str);
53int
_dprintf(
const  char  *fmt,
...) __PRINTFLIKE(1, 2);
54int
_dvprintf(
const  char  *fmt,  va_list  ap);
55
56#define
dputc(level, str) 
do  {  if  ((level)
<= DEBUGLEVEL) { _dputc(str); } } 
while  (0)
57#define
dputs(level, str) 
do  {  if  ((level)
<= DEBUGLEVEL) { _dputs(str); } } 
while  (0)
58#define
dprintf(level, x...) 
do  {  if  ((level)
<= DEBUGLEVEL) { _dprintf(x); } } 
while  (0)
59#define
dvprintf(level, x...) 
do  {  if  ((level)
<= DEBUGLEVEL) { _dvprintf(x); } } 
while  (0)

然后调用bs_set_timestamp设置启动状态为BS_BL_START,启动状态的其他值定义在bootable/bootloader/lk/platform/msm_shared/include/boot_stats.h中:

bootable/bootloader/lk/platform/msm_shared/include/boot_stats.h  Collapse
source
33 /*
The order of the entries in this enum does not correspond to bootup order.
34
* It is mandated by the expected order of the entries in imem when the values
35
* are read in the kernel.
36
*/
37enum
bs_entry {
38 
BS_BL_START = 0,
39 
BS_KERNEL_ENTRY,
40 
BS_SPLASH_SCREEN_DISPLAY,
41 
BS_KERNEL_LOAD_TIME,
42 
BS_KERNEL_LOAD_START,
43 
BS_KERNEL_LOAD_DONE,
44 
BS_MAX,
45};

2.6 SPEW同样是在bootable/bootloader/lk/include/debug.h中定义的debug
level,函数call_constructors完成相关构造函数的初始化。

2.7 调用函数heap_init完成内核堆栈的初始化,用与kmalloc等函数的内存分配。

2.8  __stack_chk_guard_setup()其实是个宏,定义在bootable/bootloader/lk/include/debug.h中,

#define __stack_chk_guard_setup() do { __stack_chk_guard = get_canary(); } while(0)
get_canary函数定义在bootable/bootloader/lk/platform/msm_shared/scm.c中,返回一个生成的随机数,最终保存在全局变量__stack_chk_guard中。

2.9  在thread_init函数中初始化定时器

2.10 初始化延迟过程调用(delay procedure call)

2.11 调用timer_init初始化内核定时器

2.12 如果没有定义ENABLE_NANDWRITE,就创建出一个名为bootstrap2的线程,然后运行这个线程。退出临界区,开中断。全局变量critical_section_count在定义时取值为1,在exit_critical_section中会将critical_section_count先减1,如果减一后为0就使能中断。

bootable/bootloader/lk/include/kernel/thread.h  Collapse
source
136static  inline  __ALWAYS_INLINE  void  exit_critical_section( void )
137{
138
critical_section_count--;
139  if  (critical_section_count
== 0)
140    
arch_enable_ints();
141}

最后调用thread_become_idle将本线程切换到idle状态

2.13 如果定义了ENABLE_NANDWRITE,在timer_init之后将执行bootstrap_nandwrite。我们接下来先以没有定义ENABLE_NANDWRITE来进行分析。




2. 二  bootstrap2

bootstrap2线程会执行bootstrap2函数

bootable/bootloader/lk/kernel/kmain.c  Collapse
source
static  int  bootstrap2( void  *arg)
{
     dprintf(SPEW,  "top
of bootstrap2()\n"
);
     arch_init();
     //
XXX put this somewhere else
#if
WITH_LIB_BIO
     bio_init();
#endif
#if
WITH_LIB_FS
     fs_init();
#endif
     //
initialize the rest of the platform
     dprintf(SPEW,  "initializing
platform\n"
);
     platform_init();
     //
initialize the target
     dprintf(SPEW,  "initializing
target\n"
);
     target_init();
     dprintf(SPEW,  "calling
apps_init()\n"
);
     apps_init();
     return  0;
}

2.1. 1 arch_init

 

arch_init函数目前实现为空。如果定义了WITH_LIB_BIO和WITH_LIB_FS,就分别执行bio_init和fs_init。函数platform_init的实现也跟cpu关联,但基本都是输出调试信息。

2.2. 2 target_init

target_init的实现也与cpu型号有关,对于mido,其cpu型号为msm8953,target_init的实现为:
bootable/bootloader/lk/target/msm8953/init.c  Collapse
source
void  target_init( void )
{
#if
VERIFIED_BOOT
#if
!VBOOT_MOTA
     int  ret
= 0;
#endif
#endif
     dprintf(INFO,  "target_init()\n" );
     spmi_init(PMIC_ARB_CHANNEL_NUM,
PMIC_ARB_OWNER_ID);
     target_keystatus();
     target_sdc_init();
     if  (partition_read_table())
     {
         dprintf(CRITICAL,  "Error
reading the partition table info\n"
);
         ASSERT(0);
     }
#if
LONG_PRESS_POWER_ON
     shutdown_detect();
#endif
#if
PON_VIB_SUPPORT
     vib_timed_turn_on(VIBRATE_TIME);
#endif
 
     if  (target_use_signed_kernel())
         target_crypto_init_params();
#if
VERIFIED_BOOT
#if
!VBOOT_MOTA
     clock_ce_enable(CE1_INSTANCE);
     /*
Initialize Qseecom */
     ret
= qseecom_init();
     if  (ret
< 0)
     {
         dprintf(CRITICAL,  "Failed
to initialize qseecom, error: %d\n"
,
ret);
         ASSERT(0);
     }
     /*
Start Qseecom */
     ret
= qseecom_tz_init();
     if  (ret
< 0)
     {
         dprintf(CRITICAL,  "Failed
to start qseecom, error: %d\n"
,
ret);
         ASSERT(0);
     }
     if  (rpmb_init()
< 0)
     {
         dprintf(CRITICAL,  "RPMB
init failed\n"
);
         ASSERT(0);
     }
     /*
      *
Load the sec app for first time
      */
     if  (load_sec_app()
< 0)
     {
         dprintf(CRITICAL,  "Failed
to load App for verified\n"
);
         ASSERT(0);
     }
#endif
#endif
#if
SMD_SUPPORT
     rpm_smd_init();
#endif
}
主要完成的操作有:

2.1从共享内存中读取xbl提供的pmic信息(pmic_info_populate)

2.2初始化spmi总线,用于cpu与pmic通信(spmi_init)

2.3初始化ap与rpm通信通道(rpm_glink_init)
2.4初始化按键(target_keystatus)

2.5判断内核是否签名,当使用的是签名的kernel时,需要初始加密解密引擎(target_crypto_init_params)

2.6判断是从usf还是emmc启动(platform_boot_dev_isemmc)

2.7获取分区表信息(mmc_read_partition_table)

2.8判断电池电压是否过低,过低则进入预充电(pm_appsbl_chg_check_weak_battery_status)

2.9和tz通信(qseecom_tz_init)

2.10初始化emmc或ufs中的rpmb用户加解密认证分区(rpmb_init)

2.11运行keymaster(load_sec_app)

 

3. 三  apps_init

在bootstrap2线程中最后执行apps_init,完成一些应用功能的初始化。

3.1.  1 apps_init

apps_init的实现在:

bootable/bootloader/lk/app/app.c  Collapse
source
/*
one time setup */
void  apps_init( void )
{
     const  struct  app_descriptor
*app;
     /*
call all the init routines */
     for  (app
= &__apps_start; app != &__apps_end; app++) {
         if  (app->init)
             app->init(app);
     }
     /*
start any that want to start on boot */
     for  (app
= &__apps_start; app != &__apps_end; app++) {
         if  (app->entry
&& (app->flags & APP_FLAG_DONT_START_ON_BOOT) == 0) {
             start_app(app);
         }
     }
}
static  int  app_thread_entry( void  *arg)
{
     const  struct  app_descriptor
*app = (
const  struct  app_descriptor
*)arg;
     app->entry(app,
NULL);
     return  0;
}
static  void  start_app( const  struct  app_descriptor
*app)
{
     thread_t
*thr;
     printf ( "starting
app %s\n"
,
app->name);
     thr
= thread_create(app->name, &app_thread_entry, (
void  *)app,
DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
     if (!thr)
     {
         return ;
     }
     thread_resume(thr);
}

__apps_start和__apps_end都是在连接脚本中定义的, 在  bootable/bootloader/lk/arch/arm/system-onesegment.ld中有:

__apps_start = .;


KEEP (*(.apps))


__apps_end = .;

__apps_start和__apps_end都代表两个链接地址,KEEP (*(.apps))表示所有.apps段都链接在__apps_start和__apps_end之间。

因为在bootable/bootloader/lk/include/app.h中有定义

bootable/bootloader/lk/include/app.h  Collapse
source
/*
app support api */
void  apps_init( void );  /*
one time setup */
/*
app entry point */
struct  app_descriptor;
typedef  void  (*app_init)( const  struct  app_descriptor
*);
typedef  void  (*app_entry)( const  struct  app_descriptor
*, 
void  *args);
/*
app startup flags */
#define
APP_FLAG_DONT_START_ON_BOOT 0x1
/*
each app needs to define one of these to define its startup conditions */
struct  app_descriptor
{
     const  char  *name;
     app_init 
init;
     app_entry
entry;
     unsigned  int  flags;
};
#define
APP_START(appname) struct app_descriptor _app_##appname __SECTION(".apps") = { .name = #appname,
#define
APP_END };

 所以这里将会执行在APP_START(appname)中定义的appname函数。在代码里搜索APP_START,会发现在bootable/bootloader/lk/app/aboot/aboot.c中调用APP_START来执行aboot_init函数

3.2. 2 aboot_init

aboot_init的定义为:

bootable/bootloader/lk/app/aboot/aboot.c  Collapse
source
void  aboot_init( const  struct  app_descriptor
*app)
{
     unsigned
reboot_mode = 0;
     /*
Initialise wdog to catch early lk crashes */
#if
WDOG_SUPPORT
     msm_wdog_init();
#endif
     /*
Setup page size information for nv storage */
     if  (target_is_emmc_boot())
     {
         page_size
= mmc_page_size();
         page_mask
= page_size - 1;
         mmc_blocksize
= mmc_get_device_blocksize();
         mmc_blocksize_mask
= mmc_blocksize - 1;
     }
     else
     {
         page_size
= flash_page_size();
         page_mask
= page_size - 1;
     }
     ASSERT((MEMBASE
+ MEMSIZE) > MEMBASE);
     read_device_info(&device);
     read_allow_oem_unlock(&device);
     /*
Display splash screen if enabled */
#if
DISPLAY_SPLASH_SCREEN
#if
NO_ALARM_DISPLAY
     if  (!check_alarm_boot())
{
#endif
         dprintf(SPEW,  "Display
Init: Start\n"
);
#if
ENABLE_WBC
         /*
Wait if the display shutdown is in progress */
         while (pm_app_display_shutdown_in_prgs());
         if  (!pm_appsbl_display_init_done())
             target_display_init(device.display_panel);
         else
             display_image_on_screen();
#else
         target_display_init(device.display_panel);
#endif
         dprintf(SPEW,  "Display
Init: Done\n"
);
#if
NO_ALARM_DISPLAY
     }
#endif
#endif
     target_serialno((unsigned  char  *)
sn_buf);
     dprintf(SPEW, "serial
number: %s\n"
,sn_buf);
     sprintf (secureboot_buf,  "%s" ,
is_secure_boot_enable() ? 
"1" : "0" );
     memset (display_panel_buf,  '\0' ,
MAX_PANEL_BUF_SIZE);
     /*
      *
Check power off reason if user force reset,
      *
if yes phone will do normal boot.
      */
     if  (is_user_force_reset())
         goto  normal_boot;
     dprintf(CRITICAL, "fastboot:
is_unlocked = %d\n"
,device.is_unlocked);
     /*
Check if we should do something other than booting up */
     if  (keys_get_state(KEY_VOLUMEUP)
&& keys_get_state(KEY_VOLUMEDOWN))
     {
         /***************add
by xiangchao.zhong for fastboot*********************/
         if (device.is_unlocked
== 0){
             dprintf(CRITICAL, "fastboot:
because devices has locked, so goto normal boot!\n"
);
             goto  normal_boot;
         }
         else {
         /***************add
by xiangchao.zhong for fastboot*********************/
             dprintf(ALWAYS, "dload
mode key sequence detected\n"
);
             reboot_device(EMERGENCY_DLOAD);
             dprintf(CRITICAL, "Failed
to reboot into dload mode\n"
);
             boot_into_fastboot
= 
true ;
         }
     }
         if  (!boot_into_fastboot)
         {
             if (target_build_variant_user())
             {
             if  (keys_get_state(KEY_HOME)
|| keys_get_state(KEY_VOLUMEUP))
                 boot_into_recovery
= 1;
             if  (!boot_into_recovery
&&
                 (keys_get_state(KEY_BACK)
|| keys_get_state(KEY_VOLUMEDOWN)))
                 boot_into_fastboot
= 
true ;
             } else {
             if  (keys_get_state(KEY_VOLUMEUP))
             {
                 snprintf(( char  *)boot_reason_buf,
20, 
"%s" ,  "boot_with_factory" );
                 dprintf(SPEW, "boot_reason_buf:
%s\n"
,
boot_reason_buf);
             } else
             if  (keys_get_state(KEY_VOLUMEDOWN))
                 boot_into_fastboot
= 
true ;
             }
         }
         #if
NO_KEYPAD_DRIVER
         if  (fastboot_trigger())
             boot_into_fastboot
= 
true ;
         #endif
     #if
USE_PON_REBOOT_REG
         reboot_mode
= check_hard_reboot_mode();
     #else
         reboot_mode
= check_reboot_mode();
     #endif
         if  (reboot_mode
== RECOVERY_MODE)
         {
             boot_into_recovery
= 1;
         }
         else  if (reboot_mode
== FASTBOOT_MODE)
         {
             boot_into_fastboot
= 
true ;
         }
         else  if (reboot_mode
== ALARM_BOOT)
         {
             boot_reason_alarm
= 
true ;
         }
     #if
VERIFIED_BOOT
     #if
!VBOOT_MOTA
         else  if  (reboot_mode
== DM_VERITY_ENFORCING)
         {
             device.verity_mode
= 1;
             write_device_info(&device);
         }
         else  if  (reboot_mode
== DM_VERITY_LOGGING)
         {
             device.verity_mode
= 1;
             write_device_info(&device);
         }
         else  if  (reboot_mode
== DM_VERITY_KEYSCLEAR)
         {
             if (send_delete_keys_to_tz())
                 ASSERT(0);
         }
     #endif
     #endif
normal_boot:
     
     if  (!boot_into_fastboot)
     {
         if  (target_is_emmc_boot())
         {
             if (emmc_recovery_init())
                 dprintf(ALWAYS, "error
in emmc_recovery_init\n"
);
             if (target_use_signed_kernel())
             {
                 if ((device.is_unlocked)
|| (device.is_tampered))
                 {
                 #ifdef
TZ_TAMPER_FUSE
                     set_tamper_fuse_cmd();
                 #endif
                 #if
USE_PCOM_SECBOOT
                     set_tamper_flag(device.is_tampered);
                 #endif
                 }
             }
             boot_linux_from_mmc();
         }
         else
         {
             recovery_init();
     #if
USE_PCOM_SECBOOT
         if ((device.is_unlocked)
|| (device.is_tampered))
             set_tamper_flag(device.is_tampered);
     #endif
             boot_linux_from_flash();
         }
         dprintf(CRITICAL,  "ERROR:
Could not do normal boot. Reverting "
             "to
fastboot mode.\n"
);
     }
     /*
We are here means regular boot did not happen. Start fastboot. */
     /*
register aboot specific fastboot commands */
     aboot_fastboot_register_commands();
     /*
dump partition table for debug info */
     partition_dump();
     /*
initialize and start fastboot */
     fastboot_init(target_get_scratch_address(),
target_get_max_flash_size());
//#if
FBCON_DISPLAY_MSG
     //display_fastboot_menu();
     display_fastboot();
//#endif
}

在aboot_init中完成的操作主要有:

2.1 根据target_is_emmc_boot()判断是否是从emmc存储设备上启动,然后分别获取对应存储设备的页大小和页掩码

2.2 取得设备的device_info信息,保存到device变量中。device_info结构体定义为:

/bootable/bootloader/lk/app/aboot/devinfo.h  Collapse
source
#if
VBOOT_MOTA
struct  device_info
{
     unsigned  char  magic[DEVICE_MAGIC_SIZE];
     bool  is_unlocked;
     bool  is_tampered;
     bool  is_verified;
     bool  charger_screen_enabled;
     char  display_panel[MAX_PANEL_ID_LEN];
     char  bootloader_version[MAX_VERSION_LEN];
     char  radio_version[MAX_VERSION_LEN];
     char  sig[SIG_SIZE];
};
#else
struct  device_info
{
     unsigned  char  magic[DEVICE_MAGIC_SIZE];
     bool  is_unlocked;
     bool  is_tampered;
     bool  is_unlock_critical;
     bool  charger_screen_enabled;
     char  display_panel[MAX_PANEL_ID_LEN];
     char  bootloader_version[MAX_VERSION_LEN];
     char  radio_version[MAX_VERSION_LEN];
     bool  verity_mode;  //
1 = enforcing, 0 = logging
     char  sig[SIG_SIZE];
};
#endif

这个结构体中包含的信息有:是否禁用fastboot,是否验证boot.img等。

2.3 调用target_display_init初始化lcd驱动,显示手机开机后的第一副图片。splash一般代表在系统启动阶段显示器用图形而非文本现实。

2.4 调用target_serialno获取emmc或者flash芯片的产品序列号,最后在启动kernel时通过cmdline中的androidboot.serialno参数传给内核。

2.5 调用memset清除屏幕

2.6 判断关机原因,如果是用户强制重启手机,这时在重启后跳转到normal_boot继续执行

2.7 判断音量上下键是否同时按下,之后如果进入下载模式失败,就设置fastboot模式标志boot_into_fastboot = true。

2.8 如果不是通过usb+上下键进入下载模式,判断如果home键和音量上键同时按下,设置recovery模式标志boot_into_recovery = 1, 如果back键和音量下键同时按下,设置fastboot模式标志。

2.9 如果没有按键驱动,设置boot_into_fastboot为true

2.10 根据硬件是否存在pon寄存器,调用check_hard_reboot_mode或者check_reboot_mode获取重启模式reboot_mode,设置相应的开机模式标志。以前使用的是共享内存记录重启模式,最新转为使用pmic的pon寄存器记录重启模式。

如果reboot_mode为RECOVERY_MODE,boot_into_recovery = 1

如果reboot_mode为FASTBOOT_MODE,boot_into_fastboot = 1

如果reboot_mode为ALARM_BOOT,boot_reason_alarm = true,这种情况时如果开启了闹钟并且设置了关机后闹钟有效,在关机后闹钟仍然会启动手机

2.11 在normal_boot:下,首先判断如果不是fastboot模式,然后通过target_is_emmc_boot判断是否从emmc或者ufs启动,

如果从emmc或者ufs启动,先执行emmc_recovery_init,emmc_recovery_init的实现主要在函数_emmc_recovery_init中,_emmc_recovery_init的定义在bootable/bootloader/lk//app/aboot/recovery.c中,主要工作为读取misc分区中的bcb,判断bcb的command域是否为boot-recovery,如果是update-radio还会检查radio的更新状态。 回到aboot_init中用target_use_signed_kernel判断是否使用了签名的kernel,最后执行boot_linux_from_mmc, 在boot_linux_from_mmc中将从emmc/ufs加载boot.img,选择dts,设置cmdline,跳转到kernel。

如果从nand flash启动,调用boot_linux_from_flash去启动内核。

2.12 之后的代码是fasboot模式或者正常启动失败的情况下才会执行到的,首先调用aboot_fastboot_register_commands注册fastboot支持的命令,在partition_dump中打印分区表信息, 执行fastboot_init初始化并启动fastboot,在display_fastboot_menu_thread中为fastboot提供了一个简易图形显示。

 

Android系统启动流程源码解析 当Android手机从按下开机键时,屏幕点亮,到系统桌面的显示,整个过程系统是怎么启动的?下面我们一起深入源码来看一下。 阅读详情

相关推荐

高通平台fingerprint指纹框架

指纹是android系统中目前应用比较广发的一种安全验证手段,它使得我们的手机安全得到了极大的提高,同时指纹它也拥有了极高权限,这就意味着,对于指纹这个软件需要一个绝对安全的运行环境,让外界很难突破去破解它。在高通平台中,手机内是分为安全环境和非安全环境的,安全环境是trustzone,简称TZ,这这里面运行的应用程序被称为qsapp,是需要经过签名验证通过才能运行,除TZ意外的地方被称为非安全环境,如下图:trustzone由两部分软件组成:TZBSP(TrustZone board support pa

小小博客 1万+

Android启动流程分析之一:Bootloader(基于高通芯片) 【mtk lk阶段有类似】

http://blog.youkuaiyun.com/ly890700/article/details/54586448 注:很多内容和MTK  LK阶段相同,可以借鉴学习。aboot.c内容差异很大。 本文以C6的bootlader代码为例,   一  kmain 1 crt0.S2 kmain 二  bootstrap2 1 arch_

ffmxnjm的博客 9204

[Android]高通平台BootLoader启动流程

一、什么是BootLoader BootLoader代码是芯片复位后,进入操作系统之前执行的一段代码。主要用于完成由硬件启动到操作系统启动的过渡,从而为操作系统提供基本的运行环境。 BootLoder主要的启动流程可以概括为:PBL阶段、SBL阶段、LK阶段。之后会加载并启动kernel。 二、名词解释 5个处理器:  APPS :Cortex A53 core(MSM8953),运...

Ekko的博客 1万+

Android 进阶——系统启动之BootLoader 及内核启动一(下)

手机电源被打开时,首先是引导进入BootLoader分区加载Linux 内核并解析执行init.rc脚本.

最美不过,心中有梦,身旁有你! 803

高通平台MSM8916LCM模块移植(一)-bootloader部分

这篇BLOG是对高通MSM8916平台的LK部分的LCM移植进行说明

penghcai的专栏 3869

MTK Android平台开发流程

主要介绍了MTK在Android平台开发的流程,一共分析了44个步骤,需要的朋友学习下吧。

高通平台Bootloader启动流程【转】

本文转载自:http://blog.youkuaiyun.com/fang_first/article/details/49615631 ====================基本知识======================= LK是(L)ittle (K)ernel的缩写。 高通平台android普遍采用LK作为其bootloader,LK是一个开源项目。但是,LK只是整个系统的引导部...

1014

STM32掉电保存配置参数技巧

本文介绍了使用STM32内置备份寄存器(BKP)实现掉电保存配置参数的方法。相比外接EEPROM或Flash,备份寄存器无需外设但存储容量有限,需通过VBAT引脚连接纽扣电池供电。文章详细说明了初始化步骤,包括使能PWR时钟、允许访问备份寄存器等操作,并提供了RTC初始化的代码示例。同时介绍了HAL库中读写备份寄存器的函数使用方法,包括HAL_RTCEx_BKUPWrite和HAL_RTCEx_BKUPRead函数的具体参数和调用示例。该方法适用于需要小容量数据掉电保存的应用场景。

hanhanhan233的博客 947

高通平台Android源码bootloader分析之sbl1(一)

高通8k平台的boot过程搞得比较复杂, 我也是前段时间遇到一些问题深入研究了一下才搞明白。不过虽然弄得很复杂,我们需要动的东西其实很少,modem侧基本就sbl1(全称:Secondary boot loader)的代码需要动一下,ap侧就APPSBL代码需要动(对此部分不了解,可参照:bootable源码解析),其他的都是高通搞好了的,甚至有些我们看不到代码。今天就要分析一下开机前几秒钟起着关...

qq_36781842的博客 6780

常见的十大量化投资策略(附源码)

量化投资策略是利用量化的方法,进行金融市场的分析、判断和交易的策略、算法的总称。著名的量化投资策略有以下10种(注:策略源码模板不能直接用于实盘交易,仅供探讨交流) 01、海龟交易策略 海龟交易策略是一套非常完整的趋势跟随型的自动化交易策略。这个复杂的策略在入场条件、仓位控制、资金管理、止损止盈等各个环节,都进行了详细的设计,这基本上可以作为复杂交易策略设计和开发的模板。 海龟交易策略源码:https://www.myquant.cn/docs/python_strategyies/110 0.

小壁虎的春天 2万+

宇树机器人G1二次开发:语音对话、打断与激活功能实现指南

宇树机器人G1是一款功能强大的四足机器人,其开放的SDK和API为开发者提供了广阔的二次开发空间。其中,语音交互是提升机器人智能化水平和用户体验的关键功能。本文将详细介绍如何在宇树机器人G1上进行二次开发,实现。语音打断允许用户在机器人说话时随时中断并输入新指令,这是提升交互自然度的关键功能。三大核心功能,帮助你构建更自然、更智能的人机交互系统。语音识别是将用户的语音输入转换为文本的过程。识别文本后,需要理解用户意图并生成回复。将文本回复转换为语音输出。

m0_52645558的博客 664

高通平台的bootloader过程【转】

target //通用init.c,具体目标板的初始化(主要为板子设备资源init.c代码中),编译规则代码(一级s810.mk二级hdc8094.mk)//只初始化串口为了打印信息,与后面的target_init对应。#if UART_INPUT_INTO_FASTBOOT //经测验,按键f要一直按住,否则很难检测到,后续可以考虑延迟一段时间。platform //不同平台代码mdmxxx,msmxxx,apqxxx,qsdxxx,还有共享的目录msm_shared。

weixin_41091711的博客 250

华硕三频万兆分布式路由组网实战:从AiMesh 2.0到全屋Wi-Fi 6覆盖

Mesh组网是解决大户型Wi-Fi覆盖难题的主流方案,其核心原理是通过多个节点构建网状网络,实现设备间的无缝漫游。在技术层面,Wi-Fi 6标准、三频设计(包括专属回程频段)和有线回程等技术,共同提升了网络的带宽、稳定性和抗干扰能力。这些技术的工程价值在于,能够为多设备并发、高带宽应用(如4K/8K流媒体、在线游戏、内网文件高速传输)提供可靠支撑。具体到应用场景,例如利用华硕AiMesh 2.0系统,配合三频万兆分布式路由器,可以实现智能的设备连接与负载均衡。通过合理规划节点位置、优先采用有线回程,并进行Q

weixin_34054866的博客 431

【Android系统启动】 BootLoader - Little Kernel启动流程源码解析

后文中的lk指 Little KernelAndroid启动会经过BootLoader阶段, BootLoader中, 挑选little kernel作为bootloader程序进行源码研究。当然也许多公司使用的是uboot,像作者公司许多项目也是使用uboot。lk官方源码中,没有集成高通、MTK平台的代码, 但是在github开源代码中,能够找到适配高通平台和MTK平台的lk,本文先是基于官方开源代码lk进行总体的分析, 然后对高通平台lk、MTK平台lk的不同部分进行分析;

thirdbro的博客 1867

Deepseek Engram 论文全面解读

以下是对 DeepSeek 与北京大学于联合发布的论文《》(简称Engram 论文)的。

lpfasd123的博客 355

高通 MSM8K bootloader : SBL1

FROM:http://blog.youkuaiyun.com/fybon/article/details/18185441 一、 MSM8K Boot Flow                                图1:   高通MSM8K平台bootloader启动流程基本类似,但具体各平台,比如MSM8974、MSM8916、MSM8

茫茫大士的专栏 2053

RK35X8调试YT8531单网口千兆以太网PHY芯片,修复ping不通或者IP地址丢失的问题

RK35X8上调试YT8531以太网PHY

荻夜的博客 3976

android lcd调试 高通平台lcd调试深入分析总结(mipi和rgb接口)

一:点亮lcd in kernel 其实点亮lcd很简单必须保证以后几个步骤正确: 1:确认Lcd信息所在文件被编译进去,并且lcd 和board name里面注册一质,倘若这部正确,那么log里面应该有对应分辨率的一段framebuffer同时调到相对应的power_on函数。对于lcdc panel对应文件在lcdc_xx.c,对于mipi panel对应文件在mipi_xx.c(下序列操

齐海谦的专栏 2085

【YOLO11改进 - 注意力机制】SCSA通过结合空间注意力和通道注意力,提高各种下游视觉任务的性能。

【YOLO11改进 - 注意力机制】SCSA通过结合空间注意力和通道注意力,提高各种下游视觉任务的性能。

专注于图像领域,主要研究内容包括计算机视觉和深度学习,特别是在图像分类、目标检测和图像生成等方面有深入的研究和实践经验。 475

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

高通bootloader 介绍

高通 MSM8K bootloader : SBL1 . 2015-05-03 14:59:36 分类: 嵌入式 一、 MSM8K Boot Flow                                图1:   高通MSM8K平台bootloader启动流程基本类似,但具体各平台,比如MSM8974、MSM8916、MSM89

manshq163com的专栏 6113

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

高通 MSM8K bootloader 之一: SBL1

高通 MSM8K bootloader 之一: SBL1  一、 MSM8K Boot Flow                               图1:   高通MSM8K平台bootloader启动流程基本类似,但具体各平台,比如MSM8974、MSM8916、MSM8994等,会有微小区别。 从上图,可以看出高通8K平台的boot过

u011279649的专栏 2181

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

高通bootloader

高通的lk启动分析

fang_first的博客 4939
上一篇: Android编译系统详解
下一篇: 高通常用缩写
makeyourprogress
博客等级 码龄11年 26粉丝 57原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值