【嵌入式Linux学习七步曲之第四篇 Linux内核移植】GDB和BDI2000调试PPC Linux内核

本文主要是介绍【嵌入式Linux学习七步曲之第四篇 Linux内核移植】GDB和BDI2000调试PPC Linux内核,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

GDB和BDI2000调试PPC Linux内核

 

Sailor_forever  sailing_9806@163.com 转载请注明
http://blog.csdn.net/sailor_8318/archive/2009/11/10/4795287.aspx

 

【摘要】本文以MPC8270处理器和Linux2.6.15.5内核为例,讲述了用BDI2000和GDB联合调试Linux内核的基本方法。给出了BDI配置脚本,内核的配置选项及调试的具体步骤,为在PPC处理器上移植Linux内核奠定了基础。
【关键字】BDI2000  GDB  MPC8270  Linux MMU  PTBASE    SIGSTOP
 
目录

BDI2000配置脚本    1
内核修改及配置    3
编译选项    3
内核配置    4
内核调试    8
GDB script    8
未开启MMU    9
开启MMU    11


BDI2000配置脚本
; bdiGDB configuration file for PUC8270/80 Board and PPCBoot and MirrorBit-Flash
; Hard Reset Configuration Word = 0x0A07B000 (RSTCONF=LOW)
; ---------------------------------------------------------
;
[INIT]
; init core register
WREG    MSR             0x00000000
;      ;clear MSR

;IMMR : internal space @ 0xFFF00000 decided by ISB of Hard Reset Configuration Word
WM32    0xFFF10004    0xFFFFFFC3    ;SYPCR: disable watchdog
WM32    0xFFF10C80    0x00000001    ;SCCR : normal operation
WM32    0xFFF10024    0x00040000    ;BCR init
WM32    0xFFF10000    0x00000000    ;SIUMCR init
WM32    0xFFF10C94    0x00000000      ;RMR init

; init memory controller
; Flash S29GL128M10, 16MB, 100ns
WM32    0xFFF10104    0xFF001846    ;OR0: Data buffer dis., 6 w.s., ext.hold on read, tc=8*15ns=120ns
WM32    0xFFF10100    0x00001001    ;BR0: Flash @0x00000000, 16bit, no parity,default value for low boot memory mode instead of the eventual value

[TARGET]
CPUTYPE     8270        ;the CPU type (603EV,750,8240,8260)
JTAGCLOCK   0          ;use 16.6 MHz JTAG clock
BOOTADDR    0x00000100  ;boot address used for start-up break, decided by CIP of Hard Reset Configuration Word
BDIMODE     AGENT         ;the BDI working mode (LOADONLY | AGENT | GATEWAY)
BREAKMODE   HARD          ;SOFT or HARD, HARD uses PPC hardware breakpoints
STEPMODE    HWBP       ;TRACE or HWBP, HWPB uses a hardware breakpoint
MMU         XLAT       ;In order to support Linux kernel debugging when MMU is on, the BDI translates effective (virtual) to physical addresses.
PTBASE      0xf0       ;the physical memory address where the BDI looks for the virtual address of the array with the two page table pointers, setup in the kernel
;VECTOR      NOCATCH      ;catch unhandled exceptions
;DCACHE      NOFLUSH    ;data cache flushing (FLUSH | NOFLUSH)
POWERUP     3000        ;start delay after power-up detected in ms
REGLIST     ALL         ;select registers needed init to transfer to CPU
STARTUP         RESET  ;for programming
;STARTUP        RUN    ;for gdb debug
WAKEUP            1000
;MEMDELAY        2000


[HOST]
IP          150.236.68.171   ;tftp sever ip where to get download image
LOAD        MANUAL      ;load code MANUAL or AUTO after reset
DEBUGPORT   2001        ;network port for gdb debug
PROMPT      PUC8270>    ;new prompt for Telnet
DUMP        E:/temp/dump.bin

[FLASH]
CHIPTYPE    MIRRORX16   ;Flash type: AMD MirrorBit
CHIPSIZE    0x1000000   ;The size of one flash chip in bytes (e.g. S29GL128M10 = 0x1000000)
BUSWIDTH    16          ;The width of the flash memory bus in bits (8 | 16 | 32 | 64)
FILE        pboot.bin   ;default file to program, here is TMN PBOOT
FORMAT      BIN
;WORKSPACE   0xFFF00000    ;workspace in int. target RAM for fast download; download is stable without this, but fast with it.

;default for erase command, total size should be larger the size of download image
ERASE       0x00000000  ;erase sector (128K) of flash
ERASE       0x00020000  ;erase sector (128K) of flash
ERASE       0x00040000  ;erase sector (128K) of flash
ERASE       0x00060000  ;erase sector (128K) of flash
ERASE       0x00080000  ;erase sector (128K) of flash
ERASE       0x000a0000  ;erase sector (128K) of flash

[REGS]
DMM1        0xFFF00000  ;IMMR base
FILE        $reg8280.def
 
配置文件的规则可以参考http://blog.csdn.net/sailor_8318/archive/2009/10/30/4745793.aspx的4.9.1    BDI configuration file for debug章节
对于Linux内核打开MMU后的调试,需要在配置文件中打开相关配置选项:MMU和PTBASE
MMU    XLAT在MMU打开之后,BDI访问内存时,会根据BAT、内核和用户页表及默认的映射关系(KERNELBASE + 0x0FFFFFFF) to
0x00000000...0x0FFFFFFF将虚拟地址转换为物理地址。MMU未打开时,将不进行地址转换,此时因为符号表中的地址为虚拟地址,因此需要重定位符号表

PTBASE是存储内核页表和用户页表首地址的指针,关系如下:
PTBASE (physical address) ->
    PTE pointer pointer(virtual address) ->
           PTE kernel pointer (virtual address)
           PTE user pointer (virtual address)

PTBASE是物理地址,可以设置为MMU打开之后内核不再访问的一块内存中的任意地址,0-0x100在复位向量之下,启动之后不再使用。因此PTBASE可以设置为0-0x100之间的任意值,但是需要和 内核匹配,此值一般为0xf0。
 

内核修改及配置
编译选项
为了能够调试内核,需要生成各种调试信息,这可以通过更改内核根目录下面的Makefile实现
-g GDB调试必备的编译参数
-O 优化选项,Linux的优化级别一般为O2,会根据性能及代码大小进行相关优化,优化后的代码和C源代码会有不一致的情况,不便于单步调试
-fomit-frame-pointer 优化函数栈回溯,当有此选项时,函数调用时可能会把参数放在寄存器中,不便于查看函数调用时的参数传递关系,因此应该去掉。可以添加-fno-omit-frame-pointer选项
-gdwarf-2 可以在GDB中看出相关宏定义。正常情况下,宏定义在编译时会进行替换,添加-gdwarf-2可以生成相关宏信息。

上述编译选项可以通过CONFIG_DEBUG_INFO来统一控制,更改如下:
ifdef CONFIG_DEBUG_INFO
CFLAGS        += -O
else
ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
CFLAGS        += -Os
else
CFLAGS        += -O2
endif
endif
#sailing cancel optimisation 20091103.

ifdef CONFIG_DEBUG_INFO
CFLAGS        += -fno-omit-frame-pointer $(call cc-option,-fno-optimize-sibling-calls,)
else
ifdef CONFIG_FRAME_POINTER
CFLAGS        += -fno-omit-frame-pointer $(call cc-option,-fno-optimize-sibling-calls,)
else
CFLAGS        += -fomit-frame-pointer
endif
endif
#sailing add stack trace 20091103

ifdef CONFIG_DEBUG_INFO
CFLAGS        += -g -gdwarf-2
endif
#sailing add -gdwarf-2 20091103

内核配置
CONFIG_DEBUG_INFO宏又是从哪里来的呢?它其实是从内核的配置文件.config里面来的。
make ARCH=ppc CROSS_COMPILE=ppc_82xx-  menuconfig

Kernel hacking  --->
[*] Kernel debugging
 [*] Include BDI-2000 user context switcher    

在2.6.15.5内核中,打开Kernel debugging选项后将自动打开Compile the kernel with debug info

保存后,以上选项会在根目录下的.config文件中生成如下配置选项:
#
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_MAGIC_SYSRQ is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_FS is not set
# CONFIG_DEBUG_VM is not set
# CONFIG_RCU_TORTURE_TEST is not set
CONFIG_WANT_EXTRA_DEBUG_INFORMATION=y
CONFIG_KGDB=y
CONFIG_KGDB_CONSOLE=y
CONFIG_KGDB_ONLY_MODULES=y
# CONFIG_XMON is not set
CONFIG_BDI_SWITCH=y


CONFIG_BDI_SWITCH选项是配合BDI2000的MMU和PTBASE参数的。其将自动在PTBASE所指向的物理内存处保存内核页表和用户页表的首地址。

arch/ppc/kernel/head.S
/* Load up the kernel context */
2:    bl    load_up_mmu

#ifdef CONFIG_BDI_SWITCH
    /* Add helper information for the Abatron bdiGDB debugger.
     * We do this here because we know the mmu is disabled, and
     * will be enabled for real in just a few instructions.
     */
    lis    r5, abatron_pteptrs@h
    ori    r5, r5, abatron_pteptrs@l
    stw    r5, 0xf0(r0)    /* This must match your Abatron config */
    lis    r6, swapper_pg_dir@h
    ori    r6, r6, swapper_pg_dir@l
    tophys(r5, r5)
    stw    r6, 0(r5)
#endif /* CONFIG_BDI_SWITCH */

swapper_pg_dir为内核页表首地址,r0为内核首地址的虚拟地址,r0+0xf0经过tophys后将转换为物理地址的0xf0,在此处存储swapper_pg_dir

在arch/ppc/kernel/head.S的最后通过abatron_pteptrs保留了8个字节的空间给BDI2000用于保存2个页表指针,如下:

/* Room for two PTE pointers, usually the kernel and current user pointers
 * to their respective root page table.
 */
abatron_pteptrs:
    .space    8

/*
 * Set up the segment registers for a new context.
 */
_GLOBAL(set_context)
    mulli    r3,r3,897    /* multiply context by skew factor */
    rlwinm    r3,r3,4,8,27    /* VSID = (context & 0xfffff) << 4 */
    addis    r3,r3,0x6000    /* Set Ks, Ku bits */
    li    r0,NUM_USER_SEGMENTS
    mtctr    r0

#ifdef CONFIG_BDI_SWITCH
    /* Context switch the PTE pointer for the Abatron BDI2000.
     * The PGDIR is passed as second argument.
     */
    lis    r5, KERNELBASE@h
    lwz    r5, 0xf0(r5)
    stw    r4, 0x4(r5)
#endif
进程切换时将当前进程的页表首地址存储在虚拟地址【KERNELBASE + 0xf0】指向的地址 + 4的偏移处,实际上就是abatron_pteptrs + 4对应的虚拟地址处。

内核调试
在内核开启MMU之前,采用的是物理地址,而符号表中的地址为虚拟地址,因此需要对符号表进行重定位,调试分两个阶段
相关规则可以参考
http://blog.csdn.net/sailor_8318/archive/2009/10/30/4745793.aspx
4.9.2    Debugging of U-Boot before relocation
同时可以利用脚本来加载符号,可参考
http://blog.csdn.net/sailor_8318/archive/2009/10/30/4745793.aspx
4.9.5    GDB script

GDB script
启动GDB时会自动调用内核根目录下的脚本.gdbinit,示例如下:
target remote 150.236.68.212:2001

define add-symbol_mmu_on
        d b
        symbol-file
        add-symbol-file vmlinux 0xC0000000
        b start_kernel
end

define reset
        d b
        symbol-file
        add-symbol-file vmlinux 0
        b __start
end

未开启MMU

PUC8270> 表示BDI2000的命令行窗口
cnbjc0052 sailing/linux-2.6.15.5>表示开发主机
(gdb) 表示是开发主机上的GDB的调试窗口中
=> 表示目标板的命令行

启动开发板
PUC8270>go
开发板启动后等待用户输入
=>
。。。。
Err:   serial
U-Boot relocated to 03fb7000
Net:   FCC1 ETHERNET
=>
停止板子的运行
PUC8270>halt
    Target CPU        : MPC8280/8220/5200 (Zeppo)
    Target state      : debug mode
    Debug entry cause : COP halt
    Current PC        : 0x03feb514
    Current CR        : 0x22000008
    Current MSR       : 0x0000a002
    Current LR        : 0x03fd540c
在__start处设置断点,注意需要先halt,否则断点未能真正设置生效
PUC8270>bi 0xc
Breakpoint identification is 1
重新使开发板运行
PUC8270>go
启动Linux内核
=> boot
*  kernel: cmdline image address = 0x00400000
## Booting kernel from Legacy Image at 00400000 ...
   Image Name:   Linux-2.6.19
   Created:      2009-11-03   8:09:41 UTC
   Image Type:   PowerPC Linux Kernel Image (gzip compressed)
   Data Size:    1285009 Bytes =  1.2 MB
   Load Address: 00000000
   Entry Point:  00000000
   Verifying Checksum ... OK
   kernel data at 0x00400040, len = 0x00139b91 (1285009)
   Uncompressing Kernel Image ... OK
   kernel loaded at 0x00000000, end = 0x002cf086
## Current stack ends at 0x03f96530
## cmdline at 0x007fff00 ... 0x007fff00
## kernel board info at 0x007ffeb0
bd address  = 0x03F96AB6
。。。。。。。。
baudrate    =  19200 bps
## No init Ramdisk
   ramdisk start = 0x00000000, ramdisk end = 0x00000000
## initrd_high = 0xffffffff, copy_to_ram = 1
   ramdisk load start = 0x00000000, ramdisk load end = 0x00000000
## Transferring control to Linux (at address 00000000) ...
   Booting using board info...

开发板在0xc断点处停止
-    TARGET: stopped
清除断点,因为8270只支持一个硬件断点,否则后面无法单步调试
PUC8270>ci
连接开发板
cnbjc0052 sailing/linux-2.6.19> ppc_82xx-gdb vmlinux
GNU gdb Red Hat Linux (6.7-1rh)
Copyright (C) 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i686-pc-linux-gnu --target=ppc-linux".
The target architecture is set automatically (currently powerpc:603)
..
0x00000000 in ?? ()
调用reset宏,更新符号表
(gdb) reset
add symbol table from file "vmlinux" at
        .text_addr = 0x0
Reading symbols from /home/sailing/ linux-2.6.15.5/vmlinux...done.
(gdb)

115             .globl  __start
116     __start:
117             mr      r31,r3                  /* save parameters */
118             mr      r30,r4
119             mr      r29,r5
120             mr      r28,r6

当需要调试MMU开启之后的代码,使用下述宏即可
(gdb) add-symbol_mmu_on


开启MMU
PUC8270>go
开发板启动后等待用户输入
=>
。。。。
Err:   serial
U-Boot relocated to 03fb7000
Net:   FCC1 ETHERNET
=>
停止板子的运行
PUC8270>halt
    Target CPU        : MPC8280/8220/5200 (Zeppo)
    Target state      : debug mode
    Debug entry cause : COP halt
    Current PC        : 0x03feb514
    Current CR        : 0x22000008
    Current MSR       : 0x0000a002
    Current LR        : 0x03fd540c
获得MMU开启之后start_kernel的首地址
cnbjc0052 sailing/linux-2.6.15.5> cat System.map | grep start_kernel
c02b2610 T start_kernel
在start_kernel处设置断点,注意需要先halt,否则断点未能真正设置生效
PUC8270>bi 0xc02b2610
Breakpoint identification is 1

重新使开发板运行
PUC8270>go
启动Linux内核
=> boot
*  kernel: cmdline image address = 0x00400000
## Booting kernel from Legacy Image at 00400000 ...
   Image Name:   Linux-2.6.19
   Created:      2009-11-03   8:09:41 UTC
   Image Type:   PowerPC Linux Kernel Image (gzip compressed)
   Data Size:    1285009 Bytes =  1.2 MB
   Load Address: 00000000
   Entry Point:  00000000
   Verifying Checksum ... OK
   kernel data at 0x00400040, len = 0x00139b91 (1285009)
   Uncompressing Kernel Image ... OK
   kernel loaded at 0x00000000, end = 0x002cf086
## Current stack ends at 0x03f96530
## cmdline at 0x007fff00 ... 0x007fff00
## kernel board info at 0x007ffeb0
bd address  = 0x03F96AB6
。。。。。。。。
baudrate    =  19200 bps
## No init Ramdisk
   ramdisk start = 0x00000000, ramdisk end = 0x00000000
## initrd_high = 0xffffffff, copy_to_ram = 1
   ramdisk load start = 0x00000000, ramdisk load end = 0x00000000
## Transferring control to Linux (at address 00000000) ...
   Booting using board info...

开发板在start_kernel断点处停止
-    TARGET: stopped
清除断点,因为8270只支持一个硬件断点,否则后面无法单步调试
PUC8270>ci
连接开发板

cnbjc0052 sailing/linux-2.6.19> ppc_82xx-gdb vmlinux
GNU gdb Red Hat Linux (6.7-1rh)
Copyright (C) 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i686-pc-linux-gnu --target=ppc-linux".
The target architecture is set automatically (currently powerpc:603)
..
0xc02b2610 in ?? ()
start_kernel () at init/main.c:479
479     {
(gdb) l 479
474     void __init __attribute__((weak)) smp_setup_processor_id(void)
475     {
476     }
477
478     asmlinkage void __init start_kernel(void)
479     {
480             char * command_line;
481             extern struct kernel_param __start___param[], __stop___param[];
482
483             smp_setup_processor_id();
(gdb)

便可开始内核的调试了,大部分板级的初始化代码将在这之后运行。

若BDI2000的配置脚本中没有MMU和PTBASE选项或者CONFIG_BDI_SWITCH未打开,则在MMU开启之后,使能定时器中断后,将出现异常,无法单步调试。现象如下:
491             time_init();
(gdb)

Program received signal SIGSTOP, Stopped (signal).
time_init () at arch/ppc/kernel/time.c:322
322                             sec = ppc_md.get_rtc_time();
(gdb) n
321                             elapsed += stamp - old_stamp;
(gdb)
323                     } while ( sec == old_sec && elapsed < 2*HZ*tb_ticks_per_jiffy);
(gdb)
322                             sec = ppc_md.get_rtc_time();
(gdb)
321                             elapsed += stamp - old_stamp;
(gdb)
323                     } while ( sec == old_sec && elapsed < 2*HZ*tb_ticks_per_jiffy);
(gdb)

Program received signal SIGSTOP, Stopped (signal).
0xc000c248 in tqm8260_get_rtc_time () at arch/ppc/platforms/tqm8260_setup.c:36
36      }
(gdb)

Program received signal SIGSTOP, Stopped (signal).
0xc000c244 in tqm8260_get_rtc_time () at arch/ppc/platforms/tqm8260_setup.c:36
36      }
(gdb)

Program received signal SIGSTOP, Stopped (signal).
0xc01bd3fc in time_init () at arch/ppc/kernel/time.c:323
323                     } while ( sec == old_sec && elapsed < 2*HZ*tb_ticks_per_jiffy);
(gdb)

Program received signal SIGSTOP, Stopped (signal).
time_init () at arch/ppc/kernel/time.c:321
321                             elapsed += stamp - old_stamp;
(gdb)
323                     } while ( sec == old_sec && elapsed < 2*HZ*tb_ticks_per_jiffy);
(gdb)

Program received signal SIGSTOP, Stopped (signal).
0xc000c248 in tqm8260_get_rtc_time () at arch/ppc/platforms/tqm8260_setup.c:36
36      }
(gdb)

Program received signal SIGSTOP, Stopped (signal).
0xc000c248 in tqm8260_get_rtc_time () at arch/ppc/platforms/tqm8260_setup.c:36
36      }
(gdb)

Program received signal SIGSTOP, Stopped (signal).
0xc01bd3fc in time_init () at arch/ppc/kernel/time.c:323
323                     } while ( sec == old_sec && elapsed < 2*HZ*tb_ticks_per_jiffy);

这篇关于【嵌入式Linux学习七步曲之第四篇 Linux内核移植】GDB和BDI2000调试PPC Linux内核的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/284512

相关文章

Linux如何查看文件权限的命令

《Linux如何查看文件权限的命令》Linux中使用ls-R命令递归查看指定目录及子目录下所有文件和文件夹的权限信息,以列表形式展示权限位、所有者、组等详细内容... 目录linux China编程查看文件权限命令输出结果示例这里是查看tomcat文件夹总结Linux 查看文件权限命令ls -l 文件或文件夹

idea的终端(Terminal)cmd的命令换成linux的命令详解

《idea的终端(Terminal)cmd的命令换成linux的命令详解》本文介绍IDEA配置Git的步骤:安装Git、修改终端设置并重启IDEA,强调顺序,作为个人经验分享,希望提供参考并支持脚本之... 目录一编程、设置前二、前置条件三、android设置四、设置后总结一、php设置前二、前置条件

Linux系统中查询JDK安装目录的几种常用方法

《Linux系统中查询JDK安装目录的几种常用方法》:本文主要介绍Linux系统中查询JDK安装目录的几种常用方法,方法分别是通过update-alternatives、Java命令、环境变量及目... 目录方法 1:通过update-alternatives查询(推荐)方法 2:检查所有已安装的 JDK方

Linux系统之lvcreate命令使用解读

《Linux系统之lvcreate命令使用解读》lvcreate是LVM中创建逻辑卷的核心命令,支持线性、条带化、RAID、镜像、快照、瘦池和缓存池等多种类型,实现灵活存储资源管理,需注意空间分配、R... 目录lvcreate命令详解一、命令概述二、语法格式三、核心功能四、选项详解五、使用示例1. 创建逻

Linux下在线安装启动VNC教程

《Linux下在线安装启动VNC教程》本文指导在CentOS7上在线安装VNC,包含安装、配置密码、启动/停止、清理重启步骤及注意事项,强调需安装VNC桌面以避免黑屏,并解决端口冲突和目录权限问题... 目录描述安装VNC安装 VNC 桌面可能遇到的问题总结描js述linux中的VNC就类似于Window

linux下shell脚本启动jar包实现过程

《linux下shell脚本启动jar包实现过程》确保APP_NAME和LOG_FILE位于目录内,首次启动前需手动创建log文件夹,否则报错,此为个人经验,供参考,欢迎支持脚本之家... 目录linux下shell脚本启动jar包样例1样例2总结linux下shell脚本启动jar包样例1#!/bin

在IntelliJ IDEA中高效运行与调试Spring Boot项目的实战步骤

《在IntelliJIDEA中高效运行与调试SpringBoot项目的实战步骤》本章详解SpringBoot项目导入IntelliJIDEA的流程,教授运行与调试技巧,包括断点设置与变量查看,奠定... 目录引言:为良驹配上好鞍一、为何选择IntelliJ IDEA?二、实战:导入并运行你的第一个项目步骤1

Linux之platform平台设备驱动详解

《Linux之platform平台设备驱动详解》Linux设备驱动模型中,Platform总线作为虚拟总线统一管理无物理总线依赖的嵌入式设备,通过platform_driver和platform_de... 目录platform驱动注册platform设备注册设备树Platform驱动和设备的关系总结在 l

linux批量替换文件内容的实现方式

《linux批量替换文件内容的实现方式》本文总结了Linux中批量替换文件内容的几种方法,包括使用sed替换文件夹内所有文件、单个文件内容及逐行字符串,强调使用反引号和绝对路径,并分享个人经验供参考... 目录一、linux批量替换文件内容 二、替换文件内所有匹配的字符串 三、替换每一行中全部str1为st

Linux进程CPU绑定优化与实践过程

《Linux进程CPU绑定优化与实践过程》Linux支持进程绑定至特定CPU核心,通过sched_setaffinity系统调用和taskset工具实现,优化缓存效率与上下文切换,提升多核计算性能,适... 目录1. 多核处理器及并行计算概念1.1 多核处理器架构概述1.2 并行计算的含义及重要性1.3 并