调试内核随笔 1
有时候调试固件的时候,难免会遇到加载内核时出现各种问题,所以学习一些常用及基本的内核调试方法方便我们定位问题。
从BIOS到内核
BIOS(basic input/output system),基本输入/输出系统。
BIOS完成处理器及芯片组的初始化,并将芯片内的部分设备抽象出个别接口供内核使用俗称RunService。
UEFI是BIOS的升级版,github官网上由tiano社区开源维护,UEFI支持Shell下的Run命令进行加载与启动内核,而现如今很多方式都是通过EFi-Grub进行引导内核,因为其支持更多的分区与有其自身的众多特性。
无论是哪种方式引导内核,都可以进行指定命令行参数,所以我们先从命令行开始展开。
命令行参数
-
nr_cpus=corenum maxcpus=corenum: 该参数可以指定允许内核BootCore时,调度多少个核进入Kernel.
如果想要详细了解,可以通过查看内核源码得知nr_cpus的去向,这里就不详细说了。 -
radeon.si_support=0 amdgpu.si_support=1: 更换内核下GPU驱动从Radeon切换到AMDGPU。
-
isolcpus = coreid,,,: 决定孤立哪个核,不允许内核自动调度孤立的coreid。
-
console=ttyS0,115200n8: 将内核的启动信息通过串口ttyS0进行Uart输出。
-
root=/dev/sda1: 指定root挂载的分区为sda1。
-
linux vmlinux: 该命令是grub下加载内核的命令并配合boot跳转到内核的入口点执行。
-
tasket -c coreid ./exec.out: 在内核层,将指定调度特定的core去执行exec.out程序,配合isolcpus的不自动调度模式,可以排查特定核引起的问题。
以后将持续更新ing, 请看下面实例。
命令行参数实例1:
此行命令是UEFI引导的GRUB的命令行,其中loglevel=7就像内核下的几级调试信息一样,7是最大的输出level。
实例2:
你一定注意到了root=… 为什么不是/dev呢,因为在制作OSiso的时候已经将分区进行特定的UUID绑定。
还是继续看:
linux: 指定了加载的内核 。
root: 指定了根文件系统的位置。
console: 指定了log输出的重定向位置。
loglevel: 指定了log输出的限制。
maxcpus,nr_cpus: 指定了内核下启动的核数。
isolcpus: 指定了boot核后,内核下不自动调度的逻辑核号。
当内核正常启动后,在内核下top命令将看到有4个核进入了内核,当你运行应用的时候将看到不会占用到1,2核的CPU资源,这就是因为使用isolcpu的原因,导致内核不会自动去调度孤立的核资源。
那么如何在内核下去调用孤立的核资源呢,那就用到了tasket -c coreid ./exec.out 这条命令,将会将指定的程序运行在指定的核上。
今天就到这。