> 文档中心 > cpu负载_内核加载

cpu负载_内核加载

 

1. cpu负载_内核加载_内核编译

1.1 cpu负载

# 1.  iostat 查看cpu利用率root@mouse:~# iostatLinux 5.4.0-92-generic (mouse)  03/17/2022      _x86_64_ (1 CPU)avg-cpu:  %user   %nice %system %iowait  %steal   %idle    1.12    0.00    0.86    0.02    0.00   98.01#这里系统认为在默认采样周期內有 1.12 %的时间工作在用户空间,0.86 %的时间用在系统空间,总体上有98.01%的时间是空闲的。#收集是不可靠的  每当时间中断触发时,内核查看此刻运行的进程类型,并增加与此类型/状态进程对应的计数器的值。这种方法的问题是在两次时间中断之间系统(进程)能够在多种状态之间切换多次,而计数器只增加最后一种状态下的计数。# 2. 查看cpu 拓扑root@mouse:~# ls /sys/devices/system/cpu/cpu0/topology/core_cpuscore_siblings_list  package_cpus  thread_siblings_listcore_cpus_list  die_cpus     package_cpus_listcore_id  die_cpus_listphysical_package_idcore_siblings   die_idthread_siblings# cpu拓扑信息root@mouse:~# ls /sys/devices/system/cpucpu0     hotplug     modalias  possible  smtcpufreq  isolated    offline   power     ueventcpuidle  kernel_max  online    present   vulnerabilities


1.2 内核加载

# 1.查看依赖库的方法root@mouse:~/tool# readelf -d  samllhog | grep NEEDED 0x0000000000000001 (NEEDED)      Shared library: [libc.so.6]# 2. 断点函数 run_init_process│   1322 static int run_init_process(const char *init_filename)││   1323 {    ││   1324  const char *const *p;    ││   1325      ││B+>1326  argv_init[0] = init_filename;   ││   1327  pr_info("Run %s as init process\n", init_filename);  │└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘remote Thread 1.1 In: run_init_process    L1326 PC: 0xffffffff81000f88(gdb)[    2.423743] Freeing unused kernel image (initmem) memory: 1176K[    2.424328] Write protecting the kernel read-only data: 20480k[    2.426721] Freeing unused kernel image (text/rodata gap) memory: 2040K[    2.427545] Freeing unused kernel image (rodata/data gap) memory: 660K# 思考中... # #  http://events.jianshu.io/p/d9ae91281850  从6小点看起 内核初始化函数preserve_boot_argsel2_setup__create_page_tables__primary_switchstart_kernel6. 内核初试化6.1 preserve_boot_args把引导程序传递的4个参数保存在全局数组boot_args中。6.2 el2_setup设定内核运行的异常等级(1)当进入内核时,异常等级为1,那么在异常级别1执行内核。(2)当进入内核时,异常等级为2,支持VHE那么内核继续在2执行,如果不支持那么降到1执行内核。在虚拟化中,运行虚拟机的操作系统称为host OS,在虚拟机里面的操作系统称为guest OS,guest OS的用户进程在异常0运行,内核在异常级别1运行;kvm的特点就是直接在处理器上执行guest OS。以虚拟机KVM为例,普通的虚拟化异常等级切换,kvm模块需要穿越异常等级1和2;Arm64引入虚拟化宿主扩展后,在异常级别2执行host OS操作系统内核,kvm就不再需要从异常级别1切换到异常级别2。6.3 __create_page_tables(1)创建恒等映射,恒等映射的特点就是虚拟地址和物理地址相同,为了在开启处理器的内存管理单元的一瞬间能够平滑过渡。由__enable_mmu负责开启内存管理单元,内核把函数__enable_mmu附近的代码放在恒等映射代码节(.idmap.text)中,恒等映射代码节的起始地址存放在全局变量__idmap_text_start中,结束地址存放在全局变量__idmap_text_end中。idmap_pg_dir为恒等映射的页全局目录的地址地址。(2)在内核的页表中为内核镜像创建映射,内核镜像起始地址为_text,结束地址为_end。6.4 __primary_switch(1)调用函数__enable_mmu以开启内存管理单元。(2)调用__primary_switched,设置不同异常级别的栈指针,VBAR_EL1设置为异常向量表的起始地址,计算内核镜像起始虚拟地址和物理地址的差值,保存到全局变量kimage_voffset中,调用start_kernel。6.5 start_kernel首先初始化基础设施,即初始化内核的各个子系统,然后调用rest_init创建init和kthreadd线程。之后,init进程继续执行初始化,主要为smp作初始化和准备,启动所有从处理器,执行几倍0~7的初始化,挂载根文件系统,释放初始化代码和数据占用的内存,最后从文件系统中装载init程序,并转换成用户空间的init进程。  

2. 总结

  • 查看cpu载荷
  • 理解linux内核加载



进入linux大门可以看哈这个视屏:https://ke.qq.com/course/417774?flowToken=1042383
学习还是得靠自己。❤️


2.1 技术参考

参考链接1:https://blog.csdn.net/new_abc/article/details/12942525
参考链接2:https://blog.csdn.net/jk110333/article/details/18443453
参考链接3:http://www.360doc.com/content/12/0825/22/8093902_232349882.shtml
参考链接4:http://events.jianshu.io/p/d9ae91281850