前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >start_kernel函数部分分析

start_kernel函数部分分析

作者头像
哆哆jarvis
发布2022-08-23 14:14:05
2530
发布2022-08-23 14:14:05
举报

根据板子里面的启动信息,cat /proc/kmsg,对着代码看。

start_kernel函数分析

1. set_task_stack_end_magic(&init_task);

抽取关键部分

代码语言:javascript
复制
  //找到栈顶位置并设置个魔术字,防止堆栈 将 thread_info 的数据覆盖;
  //如果是向上生长的栈,直接通过(task_thread_info + 8K - 1)找到栈底并设置魔术字
  //内核栈大小一般为4K或者8K.
  set_task_stack_end_magic(&init_task);
    stackend = end_of_stack(tsk);
      return (unsigned long *)(task_thread_info(p) + 1);
    *stackend = STACK_END_MAGIC; // 0x57AC6E9D
代码语言:javascript
复制
//宏定义了就是向上生长
static inline unsigned long *end_of_stack(struct task_struct *p)
{
#ifdef CONFIG_STACK_GROWSUP
  return (unsigned long *)((unsigned long)task_thread_info(p) + THREAD_SIZE) - 1;
#else
  return (unsigned long *)(task_thread_info(p) + 1);
#endif
}

(栈向下生长的情况)

(栈向上生长的情况)

2. smp_setup_processor_id

代码语言:javascript
复制
  int i;
  u32 mpidr = is_smp() ? read_cpuid_mpidr() & MPIDR_HWID_BITMASK : 0;
  u32 cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);

  cpu_logical_map(0) = cpu;
  for (i = 1; i < nr_cpu_ids; ++i)
    cpu_logical_map(i) = i == cpu ? 0 : i;

  /*
   * clear __my_cpu_offset on boot CPU to avoid hang caused by
   * using percpu variable early, for example, lockdep will
   * access percpu variable inside lock_release
   */
  set_my_cpu_offset(0);

  pr_info("Booting Linux on physical CPU 0x%x\n", mpidr);

先通过is_smp()函数判断是否为smp处理器

代码语言:javascript
复制
static inline bool is_smp(void)
{
#ifndef CONFIG_SMP
  return false;
#elif defined(CONFIG_SMP_ON_UP)
  extern unsigned int smp_on_up;
  return !!smp_on_up;
#else
  return true;
#endif
}

我的是imx6ull板子,不是对称多处理器,这里宏没定义,直接返回false。

所以mpidr 为0

3. local_irq_disable

暂时禁止本地中断, 设置完相关的东西后再开启

代码语言:javascript
复制
  // 禁止本地中断
  local_irq_disable
    raw_local_irq_disable
      arch_local_irq_disable

4. boot_cpu_init

初始化 Boot CPU

代码语言:javascript
复制
  // 设置boot cpu
  boot_cpu_init
    smp_processor_id
      raw_smp_processor_id
        current_thread_info()->cpu
    set_cpu_online
    set_cpu_active
    set_cpu_present
    set_cpu_possible

5.page_address_init

初始化高端内存线性地址中永久映射的全局变量.IMX6ULL这里的宏没开,所以这里应该是空

代码语言:javascript
复制
  page_address_init
    // page_address_htable 是个全局结构体数组, 
    for (i = 0; i < ARRAY_SIZE(page_address_htable); i++)
      INIT_LIST_HEAD(&page_address_htable[i].lh);
      spin_lock_init(&page_address_htable[i].lock);

6.pr_notice("%s", linux_banner);

linux_banner 字符串保存了 linux 版本号,编译主机,GCC 版本,编译 时间等信息。在开机过程中可以看到log

代码语言:javascript
复制
/* FIXED STRINGS! Don't touc.h! */
const char linux_banner[] =
  "Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@"
  LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n";

以下是编译生成的文件,路径在include\generated\compile.h

代码语言:javascript
复制
#define UTS_MACHINE "arm"
#define UTS_VERSION "#9 SMP PREEMPT Sat Dec 25 20:49:44 CST 2021"
#define LINUX_COMPILE_BY "zrc"
#define LINUX_COMPILE_HOST "zrc"
#define LINUX_COMPILER "gcc version 4.9.4 (Linaro GCC 4.9-2017.01) "

7. setup_arch

初始化体系相关的部分,实现与体系和芯片有关

代码语言:javascript
复制
  // 初始化体系相关的部分,实现与体系和芯片有关
  setup_arch(&command_line)
    setup_processor(); // 从硬件获得体系相关的信息,并将该信息用于系统的初始化
    // __atags_pointer 指向 DTB 所在的物理地址
    mdesc = setup_machine_fdt(__atags_pointer)
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-12-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 哆哆jarvis 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档