8分钟掌握Linux内核分析的核心科技

【网络安全】Linux内核部分文件分析 前言 对于操作系统的分析,是一个复杂且枯燥的过程,其中包括中断、调用等一系列的问题,需要从原理和代码两层的角度进行分析,包含汇编、C语言等较为难理解的知识,以及算法的思维。 【学习资料】 启动流程 setup模块扇区长度为4个扇区,各个模块存放在内存的地址。 这里的ROOT_DEV=0x306表示第二个硬盘的第一个扇区。 基础 设备号 = 主设备号 * 256 + 次设备号 主设备号是定义好的: 1-内存 2-磁盘 3-硬盘 PC机的BIOS把bootsect的一个固定地址拿到了内存中某个固定地 阅读详情

作者:

OUYANG_LINUX007

来源:

http://blog.youkuaiyun.com/ouyang_linux007/article/details/7422346


Linux的最大的好处之一就是它的源码公开。同时,公开的核心源码也吸引着无数的电脑爱好者和程序员;他们把解读和分析Linux的核心源码作为自己的最大兴趣,把修改Linux源码和改造Linux系统作为自己对计算机技术追求的最大目标。


Linux内核源码是很具吸引力的,特别是当你弄懂了一个分析了好久都没搞懂的问题;或者是被你修改过了的内核,顺利通过编译,一切运行正常的时候。那种成就感真是油然而生!而且,对内核的分析,除了出自对技术的狂热追求之外,这种令人生畏的劳动所带来的回报也是非常令人着迷的,这也正是它拥有众多追随者的主要原因:


  • 首先,你可以从中学到很多的计算机的底层知识,如后面将讲到的系统的引导和硬件提供的中断机制等;其它,象虚拟存储的实现机制,多任务机制,系统保护机制等等,这些都是非都源码不能体会的。


  • 同时,你还将从操作系统的整体结构中,体会整体设计在软件设计中的份量和作用,以及一些宏观设计的方法和技巧:Linux的内核为上层应用提供一个与具体硬 件不相关的平台;同时在内核内部,它又把代码分为与体系结构和硬件相关的部分,和可移植的部分;再例如,Linux虽然不是微内核的,但他把大部分的设备 驱动处理成相对独立的内核模块,这样减小了内核运行的开销,增强了内核代码的模块独立性。


  • 而且你还能从对内核源码的分析中,体会到它在解决某个具体细节问题时,方法的巧妙:如后面将分析到了的Linux通过Botoom_half机制来加快系统对中断的处理。


  • 最重要的是:在源码的分析过程中,你将会被一点一点地、潜移默化地专业化。一个专业的程序员,总是把代码的清晰性,兼容性,可移植性放在很重要的位置。他们总是通过定义大量的宏,来增强代码的清晰度和可读性,而又不增加编译后的代码长度和代码的运行效率;他们总是在编码的同时,就考虑到了以后的代码维护和升 级。 甚至,只要分析百分之一的代码后,你就会深刻地体会到,什么样的代码才是一个专业的程序员写的,什么样的代码是一个业余爱好者写的。而这一点是任何没有真 正分析过标准代码的人都无法体会到的。


然而,由于内核代码的冗长,和内核体系结构的庞杂,所以分析内核也是一个很艰难,很需要毅力的事;在缺乏指导和交流的情况下,尤其如此。只有方法正确,才能事半功倍。正是基于这种考虑,作者希望通过此文能给大家一些借鉴和启迪。

由于本人所进行的分析都是基于2.2.5版本的内核;所以,如果没有特别说明,以下分析都是基于i386单处理器的2.2.5版本的Linux内核。所有源文件均是相对于目录/usr/src/linux的。


1

入手方法


01

方法一


要分析Linux内核源码,首先必须找到各个模块的位置,也即要弄懂源码的文件组织形式。虽然对于有经验的高手而言,这个不是很难;但对于很多初级的Linux爱好者,和那些对源码分析很有兴趣但接触不多的人来说,这还是很有必要的。

1.Linux核心源程序通常都安装在/usr/src/linux下,而且它有一个非常简单的编号约定:任何偶数的核心(的二个数为偶数,例如2.0.30)都是一个稳定地发行的核心,而任何奇数的核心(例如2.1.42)都是一个开发中的核心。

2.核心源程序的文件按树形结构进行组织,在源程序树的最上层,即目录/usr/src/linux下有这样一些目录和文件: 


◆ COPYING: GPL版权申明。对具有GPL版权的源代码改动而形成的程序,或使用GPL工具产生的程序,具有使用GPL发表的义务,如公开源代码; 

◆ CREDITS: 光荣榜。对Linux做出过很大贡献的一些人的信息; 

◆ MAINTAINERS: 维护人员列表,对当前版本的内核各部分都有谁负责; 

◆ Makefile: 第一个Makefile文件。用来组织内核的各模块,记录了个模块间的相互这间的联系和依托关系,编译时使用;仔细阅读各子目录下的Makefile文件对弄清各个文件这间的联系和依托关系很有帮助;

◆ ReadMe: 核心及其编译配置方法简单介绍; 

◆ Rules.make: 各种Makefilemake所使用的一些共同规则; 

◆ REPORTING-BUGS: 有关报告Bug 的一些内容; 

● Arch/: arch子目录包括了所有和体系结构相关的核心代码。它的每一个子目录都代表一种支持的体系结构,例如i386就是关于intel cpu及与之相兼容体系结构的子目录。PC机一般都基于此目录;

● Include/: include子目录包括编译核心所需要的大部分头文件。与平台无关的头文件在 include/linux子目录下,与 intel cpu相关的头文件在include/asm-i386子目录下,而include/scsi目录则是有关scsi设备的头文件目录;


● Init/: 这个目录包含核心的初始化代码(注:不是系统的引导代码),包含两个文件main.c和Version.c,这是研究核心如何工作的好的起点之一。 


● Mm/: 这个目录包括所有独立于 cpu 体系结构的内存管理代码,如页式存储管理内存的分配和释放等;而和体系结构相关的内存管理代码则位于arch/*/mm/,例如arch/i386/mm/Fault.c;

● Kernel/: 主要的核心代码,此目录下的文件实现了大多数linux系统的内核函数,其中最重要的文件当属sched.c;同样,和体系结构相关的代码在arch/*/kernel中;

● Drivers/: 放置系统所有的设备驱动程序;每种驱动程序又各占用一个子目录:如,/block 下为块设备驱动程序,比如ide(ide.c)。如果你希望查看所有可能包含文件系统的设备是如何初始化的,你可以看 drivers/block/genhd.c中的device_setup()。它不仅初始化硬盘,也初始化网络,因为安装nfs文件系统的时候需要网 络;

● Documentation/: 文档目录,没有内核代码,只是一套有用的文档,可惜都是English的,看看应该有用的哦; 

● Fs/: 所有的文件系统代码和各种类型的文件操作代码,它的每一个子目录支持一个文件系统, 例如fat和ext2; 

● Ipc/: 这个目录包含核心的进程间通讯的代码; 

● Lib/: 放置核心的库代码; 

● Net/: 核心与网络相关的代码; 

● Modules/: 模块文件目录,是个空目录,用于存放编译时产生的模块目标文件; 

● Scripts/: 描述文件,脚本,用于对核心的配置; 

一般,在每个子目录下,都有一个 Makefile 和一个Readme 文件,仔细阅读这两个文件,对内核源码的理解很有用。 


对Linux内核源码的分析,有几个很好的入口点:一个就是系统的引导和初始化,即从机器加电到系统核心的运行;另外一个就是系统调用,系统调用是用户 程序或操作调用核心所提供的功能的接口。对于那些对硬件比较熟悉的爱好者,从系统的引导入手进行分析,可能来的容易一些;而从系统调用下口,则可能更合适 于那些在dos或Uinx、Linux下有过C编程经验的高手。这两点,在后面还将介绍到。

02

方法二


从表面上看,Linux的源码就象一团扎乱无章的乱麻,其实它是一个组织得有条有理的蛛网。要把整个结构分析清楚,除了找出线头,还得理顺各个部分之间的关系,有条不紊的一点一点的分析。

所谓以程序流程为线索、一线串珠,就是指根据程序的执行流程,把程序执行过程所涉及到的代码分析清楚。这种方法最典型的应用有两个:一是系统的初始化过程;二是应用程序的执行流程:从程序的装载,到运行,一直到程序的退出。

为了简便起见,遵从循序渐进的原理,现就系统的初始化过程来具体的介绍这种方法。系统的初始化流程包括:系统引导,实模式下的初始化,保护模式下的初始化共三个部分。下面将一一介绍。

linux系统的常见引导方式有两种:Lilo引导和Loadin引导;同时linux内核也自带了一个bootsect-loader。由于它只能实现 linux的引导,不像前两个那样具有很大的灵活性(lilo可实现多重引导、loadin可在dos下引导linux),所以在普通应用场合实际上很少 使用bootsect-loader。当然,bootsect-loader也具有它自己的优点:短小没有多余的代码、附带在内核源码中、是内核源码的有 机组成部分,等等。

bootsect-loader在内和源码中对应的程序是 /Arch/i386/boot/bootsect.S。下面将主要是针对此文件进行的分析。


1.几个相关文件: 

<1> /Arch/i386/boot/bootsect.S 

<2> /include/linux/config.h 

<3> /include/asm/boot.h 

<4> /include/linux/autoconf.h 


2.引导过程分析: 

对于Intel x86 PC , 开启电源后, 机器就会开始执行ROM BIOS的一系列系统测试动作,包括检查RAM,keyboard,显示器,软硬磁盘等等。执行完bios的系统测试之后,紧接着控制权会转移给ROM中 的启动程序(ROM bootstrap routine);这个程序会将磁盘上的第0轨第0扇区(叫boot sector或MBR , 系统的引导程序就放在此处)读入内存中,并放到自0x07C0:0x0000开始的512个字节处;然后处理机将跳到此处开始执行这一引导程序;也即装入 MBR中的引导程序后,CS:IP = 0x07C0:0x0000 。加电后处理机运行在与8086相兼容的实模式下。 


如果要用 bootsect-loader进行系统引导,则必须把bootsect.S编译连接后对应的二进制代码置于MBR; 当ROM BIOS 把bootsect.S编译连接后对应的二进制代码装入内存后,机器的控制权就完全转交给bootsect; 也就是说,bootsect将是第一个被读入内存中并执行的程序。

Bootsect接管机器控制权后,将依次进行以下一些动作: 

2.1 首先,bootsect将它"自己"(自位置0x07C0:0x0000开始的512个字节)从被ROM

BIOS载入的地址0x07C0:0x0000处搬到0x9000:0000处; 这一任务由bootsect.S的

前十条指令完成;第十一条指令“jmpi go,INITSEG”则把机器跳转到“新”的bootsect的“jmpi go,INITSEG”后的那条指令“go: mov di,#0x4000-12”;之后,继续执行bootsect的剩下的代码;在bootsect.S中定义了几个常量:


BOOTSEG = 0x07C0 bios 载入 MBR的约定位置的段址; 

INITSEG = 0x9000 bootsect.S的前十条指令将自己搬到此处(段址) 

SETUPSEG =0x9020 装入Setup.S的段址 

SYSSEG =0x1000 系统区段址 

对于这些常量可参见/include/asm/boot.h中的定义;这些常量在下面的分析中将会经常用到; 

2.2 以0x9000:0x4000-12为栈底,建立自己的栈区;其中0x9000:0x4000-12到0x9000:0x4000的一十二个字节预留作磁盘参数表区; 


2.3 在0x9000:0x4000-12到0x9000:0x4000的一十二个预留字节中建立新的磁盘参数表,之所以叫“新”的磁盘参数表,是相对于 bios建立的磁盘参数表而言的。由于设计者考虑到有些老的bios不能准确地识别磁盘“每个磁道的扇区数”,从而导致

bios建立的磁盘参数表妨碍磁盘 的最高性能发挥,所以,设计者就在bios建立的磁盘参数表的基础上通过枚举法测试,试图建立准确的“新”的磁盘参数表(这是在后继步骤中完成的);并把 参数表的位置由原来的0x0000:0x0078搬到0x9000:0x4000-12;且修改老的磁盘参数表区使之指向新的磁盘参数表;


2.4 接下来就到了load_setup子过程;它调用0x13中断的第2号服务;把第0道第2扇区开始的连续的setup_sects (为常量4)个扇区读到紧邻bootsect的内存区;即0x9000:0x0200开始的2048个字节;而这四个扇区的内容即是 /arch/i386/boot/setup.S编译连接后对应的二进制代码; 也就是说,如果要用bootsect-loader进行系统引导,不仅必须把bootsect.S编译连接后对应的二进制代码置于MBR,而且还得把 setup.S编译连接后对应的二进制代码置于紧跟MBR后的连续的四个扇区中;当然,由于setup.S对应的可执行码是由bootsect装载的,所以,在我们的这个项目中可以通过修改bootsect来根据需要随意地放置setup.S对应的可执行码; 


2.5 load_setup子过程的唯一出口是probe_loop子过程;该过程通过枚举法测试磁盘“每个磁道的扇区数”; 


2.6 接下来几个子过程比较清晰易懂:打印我们熟悉的“Loading”;读入系统到0x1000:0x0000; 关掉软驱马达;根据的5步测出的“每个磁道的扇区数”确定磁盘类型;最后跳转到0x9000:0x0200,即setup.S对应的可执行码的入口,将机 器控制权转交setup.S;整个bootsect代码运行完毕;


3.引导过程执行完后的内存印象图:

出于简便考虑,在此分析中,我忽略了对大内核的处理的分析,因为对大内核的处理,只是此引导过程中的一个很小的部分,并不影响对整体的把握。完成了系统的引导后,系统将进入到初始化处理阶段。系统的初始化分为实模式和保护模式两部分。


2

实模式下的初始化


实模式下的初始化,主要是指从内核引导成功后,到进入保护模式之前系统所做的一些处理。在内核源码中对应的程序是 /Arch/i386/boot/setup.S;以下部分主要是针对此文件进行的分析。这部分的分析主要是要弄懂它的处理流程和INITSEG (9000:0000)段参数表的建立,此参数表包含了很多硬件参数,这些都是以后进行保护模式下初始化,以及核心建立的基础。


1.几个其它相关文件: 

<1> /Arch/i386/boot/bootsect.S 

<2> /include/linux/config.h 

<3> /include/asm/boot.h 

<4> /include/ asm/segment.h 

<5> /include/linux/version.h 

<6> /include/linux/compile.h 

2.实模式下的初始化过程分析: 



INITSEG(9000:0000)段参数表:(参见Include/linux/tty.h)

参数名

偏移量(段址均为0x9000) 长度Byte

参考文件

PARAM_CURSOR_POS 0x0000 2 Arch/i386/boot/video.S
extended mem Size 0x0002 2 Arch/i386/boot/setup.S

PARAM_VIDEO_PAGE

0x0004 2 Arch/i386/boot/video.S
PARAM_VIDEO_MODE 0x0006 1 Arch/i386/boot/video.S
PARAM_VIDEO_COLS 0x0007 1 Arch/i386/boot/video.S
没用 0x0008 2 Include/linux/tty.h
PARAM_VIDEO_EGA_BX 0x000a 2 Arch/i386/boot/video.S
没用 0x000c 2 Include/linux/tty.h
PARAM_VIDEO_LINES 0x000e 1 Arch/i386/boot/video.S
PARAM_HAVE_VGA 0x000f 1 Arch/i386/boot/video.S
PARAM_FONT_POINTS 0x0010 2 Arch/i386/boot/video.S
PARAM_LFB_WIDTH 0x0012 2 Arch/i386/boot/video.S
PARAM_LFB_HEIGHT 0x0014 2 Arch/i386/boot/video.S
PARAM_LFB_DEPTH 0x0016 2 Arch/i386/boot/video.S
PARAM_LFB_BASE 0x0018 4 Arch/i386/boot/video.S
PARAM_LFB_SIZE 0x001c 4 Arch/i386/boot/video.S
暂未用① 0x0020 4 Include/linux/tty.h
PARAM_LFB_LINELENGTH 0x0024 2 Arch/i386/boot/video.S
PARAM_LFB_COLORS 0x0026 6 Arch/i386/boot/video.S
暂未用② 0x002c 2 Arch/i386/boot/video.S
PARAM_VESAPM_SEG 0x002e 2 Arch/i386/boot/video.S
PARAM_VESAPM_OFF 0x0030 2 Arch/i386/boot/video.S
PARAM_LFB_PAGES 0x0032 2 Arch/i386/boot/video.S
保留 0x0034--0x003f
Include/linux/tty.h
APM BIOS Version③ 0x0040 2 Arch/i386/boot/setup.S
BIOS code segment 0x0042 2 Arch/i386/boot/setup.S
BIOS entry offset 0x0044 4 Arch/i386/boot/setup.S
BIOS 16 bit code seg 0x0048 2 Arch/i386/boot/setup.S
BIOS data segment 0x004a 2 Arch/i386/boot/setup.S
支持32位标志④ 0x004c 2 Arch/i386/boot/setup.S
BIOS code seg length 0x004e 4 Arch/i386/boot/setup.S
BIOS data seg length 0x0052 2 Arch/i386/boot/setup.S
hd0 参数 0x0080 16 Arch/i386/boot/setup.S
hd0 参数 0x0090 16 Arch/i386/boot/setup.S
PS/2 device 标志⑤ 0x01ff 1 Arch/i386/boot/setup.S


* 注: 


① Include/linux/tty.h : 

CL_MAGIC and CL_OFFSET here


② Include/linux/tty.h :

unsigned char rsvd_size; /* 0x2c */

unsigned char rsvd_pos; /* 0x2d */ 

③ 0表示没有APM BIOS 

④ 0x0002置位表示支持32位模式 

⑤ 0表示没有,0x0aa表示有鼠标器 

3

保护模式下的初始化


保护模式下的初始化,是指处理机进入保护模式后到运行系统第一个内核程序过程中系统所做的一些处理。保护模式下的初始化在内核源码中对应的程序是/Arch/i386/boot/compressed/head.S 和 /Arch/i386/KERNEL/head.S ;以下部分主要是针对这两个文件进行的分析。


1.几个相关文件: 

<1> /Arch/i386/boot/compressed/head.S 

<2> /Arch/i386/KERNEL/head.S 

<3> //Arch/i386/boot/compressed/MISC.c 

<4> /Arch/i386/boot/setup.S 

<5> /include/ asm/segment.h 

<6> /arch/i386/kernel/traps.c 

<7> /include/i386/desc.h 

<8> /include/asm-i386/processor.h 

2.保护模式下的初始化过程分析:

一、/Arch/i386/KERNEL/head.S流程: 


  
二、/Arch/i386/boot/compressed/head.S流程: 

1.从流程图中可以看到,保护模式下的初始化主要干了这样几件事:

a.解压内核到0x100000处、

b.建立页目录和pg0页表并启动分页功能(即虚存管理功能)、

c.保存实模式下测到的硬件信息到empty_zero_page、初始化命令缓存区、

d.检测cpu类型、检查协处理器、

e.重新建立gdt全局描述符表、和中断描述附表idt;


2.从页目录和pg0页表可以看出,0&#0;4M物理内存被用作系统区,它被映射到系统段线性空间的0&#0;4M和3G&#0;3G+4M;即系统可以通过访问这两个段来访问实际的0&#0;4M物理内存,也就是系统所在的区域;


3.本来在实模式下初始化时已经建立了全局描述符表gdt,而此处重新建立全局描述符表gdt则主要是出于两个原因:一个就是若内核是大内核bzimag,则以 前建立的gdt,可能已经在解压时被覆盖掉了所以,在这个源码文件中均只采用相对转移指令jxx nf或jxx nb;二是以前建立的gdt是建立在实地址方式下的,而现在则是在启用保护虚拟地址方式之后建立的,也即现在的gdt是建立在逻辑地址(即线性地址)上 的;


4.每次建立新的gdt后和启用保护虚拟地址方式后都必须重新装载系统栈和重新初始化各段寄存器:cs,ds,es,fs,gs;


5.从实模式下的初始化和保护模式下的初始化过程可以看出,linux系统由实模式进入到保护模式的过程大致如下:



6.由于分页机制只能在保护模式下启动,不能在实模式下启动,所以第一步是必要的;又因为在386保护模式下gdt和idt是建立在逻辑地址(线性地址)上的,所以第三步也是必要的;


7.经过实模式和保护模式下的初始后,主要系统数据分布如下: 


初始后主要系统数据分布表

位置 系统数据 大小
0x101000 页目录swapper_pg_dir 4K
0x102000 页表pg0 4K
0x103000 empty_bad_page 4K
0x104000 empty_bad_page_table 4K
0x105000 empty_zero_page 4K
0x105000 系统硬件参数 2K
0x105800 命令缓冲区 2K
0x106000 全局描述附表gdt_table 4192B


从上面对Linux系统的初始化过程的分析可以看出,以程序执行流程为线索、一线串珠,就是按照程序的执行先后顺序,弄懂程序执行的各个阶段所进行的处理,及其各阶段之间的相互联系。而流程图应该是这种分析方法最合适的表达工具。


事实上,以程序执行流程为线索,是分析任何源代码都首选的方法。由于操作系统的特殊性,光用这种方法是远远不够的。当然用这种方法来分析系统的初始化过程或用户进程的执行流程应该说是很有效的。

Halcon中文算子速查手册:工业视觉开发实战指南 机器视觉中的图像处理算子是工业自动化检测的核心工具,通过像素级操作实现特征提取与模式识别。Halcon作为主流视觉软件,其算子库涵盖图像采集、预处理、Blob分析等关键环节,直接影响检测精度与系统性能。在工业现场应用中,合理选择threshold阈值分割、edges_sub_pix亚像素检测等算子,可显著提升缺陷识别准确率。本手册系统整理12类高频算子的参数配置与实战技巧,特别针对PCB检测、零件定位等场景提供优化方案,帮助工程师快速解决中英文文档切换导致的效率瓶颈问题。 阅读详情

相关推荐

WSL2 原理与实战:不是虚拟机,而是 Windows 内核级 Linux 运行时

WSL2 是微软在 Windows 内核中深度集成的轻量级 Linux 运行时环境,其核心并非传统虚拟机,而是基于 Hyper-V 虚拟化层运行完整 Linux 内核的用户态执行平台。它通过 9p 文件协议实现跨系统 I/O 转发,采用独立网络栈(172.x.x.x)与双向 NAT 模型,并依赖 Windows 内核原生支持的 WSL 系统调用。技术价值在于让 gcc、make、npm、docker 等 Linux 工具链获得接近原生的性能,同时无缝复用 Windows 的 GUI、IDE 和文件系统。典型

clt3617的博客 473

【操作系统-哈工大李治军】---学习笔记(上)---操作系统启动与接口

操作系统—启动与接口 1 操作系统概述 1.1 从屏幕上输出"hello", (1)首先CPU向内存条发出指令,“hello”在内存的300位置,0X68就是h的ASCII码等,将其放在显存里地址为777;同理e到778位置等; (2)实际上经过封装,只需要printf(“hello!”)就可以,而正是**操作系统的作用!**在计算机硬件之上,包装一层软件,使得使用更加方便; 1.2 什么是操作系统 (1)课程中主要将前5个,分别是CPU管理,内存管理,终端管理,磁盘管理,文件管理; 1.3 学习操

plain_rookie的博客 2135

Linux C核心技术视频课程

分享一套课程——Linux C核心技术视频课程

Linux 内核观测技术 eBPF 中文入门指南

公众号关注「奇妙的 Linux 世界」设为「星标」,每天带你玩转 Linux !很早前就想写一篇关于 eBPF 的文章,但是迟迟没有动手,这两天有点时间,所以就来写一篇。这文章主要还是简单的介绍 eBPF 是用来干什么的,并通过几个示例来介绍是怎么玩的。这个技术非常非常之强,Linux 操作系统的观测性实在是太强大了,并在 BCC 加持下变得一览无余。这个技术不是一般的运维人员或是系统管理员可以...

easylife206的专栏 5143

linux核心技术详解 .

linux核心技术详解 .

LINUX内核技术手册2.pdf

LINUX内核技术手册2.pdf

Linux 内核观测技术BPF

BPF允许任何人在Linux内核之中执行任意的代码,这听起来的十分危险,但是由于有着使得这一过程变的相当的安全。BPF时内核的一个模块,所有的BPF程序都必须经过它的审查才能够被加载到内核之中去运行。验证器执行的就是对BPF虚拟机加载的代码进行。这一步的目的是保证程序可以按照预期去结束,而不会产生死循环拜拜浪费系统资源。验证器会创建一个DAG(有向无环图),将BPF程序的每个执行首位相连之后去执行DFS(深度优先遍历),当且仅当每个路径都能达到DAG的底部才会通过验证。之后其会执行。

0 error(s) 3356

SMRATS(一) SMARTS+PPO baseline运行教程

python类方法 class Agent: @classmethod def from_function() python typing 含义 为防止弱类型python出现忘记变量类型的问题,python3.5及之后版本增加了对应的类型提示。 输入和输出类型 函数接受并返回一个字符串,注释像下面这样: def greeting(name: str) -> str: return 'Hello ' + name 常用的typing类型 int,long,float: 整型,

Freshduke的博客 1415

linux 内核 核心代码,8分钟掌握Linux内核分析的核心科技

原标题:8分钟掌握Linux内核分析的核心科技作者:OUYANG_LINUX007来源:http://blog.youkuaiyun.com/ouyang_linux007/article/details/7422346Linux的最大的好处之一就是它的源码公开。同时,公开的核心源码也吸引着无数的电脑爱好者和程序员;他们把解读和分析Linux的核心源码作为自己的最大兴趣,把修改Linux源码和改造Linux系...

weixin_32578161的博客 329

C51编程25-应用篇(单片机与电脑端实现wifi通讯)

单片机使用ESP-01S wifi模块与电脑端进行数据通讯。

qq_34343637的博客 1万+

43、基于机器学习的GNSS信号质量监测方法

本文提出了一种基于支持向量机(SVM)的GNSS信号质量监测方法,旨在有效检测邪恶波形(EWF)威胁并抑制多径干扰对导航精度的影响。通过构建包含现场采集与合成数据的数据集,结合11个相关器测量值、链路预算、仰角和方位角等特征,采用RBF核函数的SVM模型进行分类。研究评估了不同平滑时间窗口对漏检率和误报率的影响,结果表明在约35-40秒平滑时间下性能趋于稳定,并可通过多数投票机制进一步优化检测性能。该方案适用于星载GNSS接收器,在计算资源受限条件下实现了高可靠性与低完整性风险的平衡。

yyy34的博客 190

linux内核解析,8分钟掌握Linux内核分析的核心科技

Linux的最大的好处之一就是它的源码公开。同时,公开的核心源码也吸引着无数的电脑爱好者和程序员;他们把解读和分析Linux的核心源码作为自己的最大兴趣,把修改Linux源码和改造Linux系统作为自己对计算机技术追求的最大目标。Linux内核源码是很具吸引力的,特别是当你弄懂了一个分析了好久都没搞懂的问题;或者是被你修改过了的内核,顺利通过编译,一切运行正常的时候。那种成就感真是油然而生!而且,...

weixin_42365898的博客 332

世界职业院校技能大赛—人工智能赛道项目逐字稿参考十二

世界职业院校技能大赛—人工智能赛道项目逐字稿参考十二

我是网络安全兼技能大赛工程师,专注网络安全技术学习与技能大赛实战!持续分享最新的技术文章,帮你少走弯路,一起在技术赛道上进步~ 146

Linux内存压缩黑科技:5个技巧让服务器性能飙升300%

你是否曾因服务器内存不足而彻夜难眠?当应用响应变慢、系统频繁交换时,传统解决方案往往束手无策。今天,我将揭秘Linux内核中的一项革命性技术——zram内存压缩,它能将你的服务器性能提升300%!本文将带你深入理解这项技术,并提供5个立竿见影的优化技巧。 ## 🎯 内存危机的真实场景:从卡顿到流畅的转变 想象一下这个场景:凌晨3点,你的电商平台迎来促销高峰,内存使用率飙升至95%,系统开始疯

gitblog_00052的博客 480

02 HCM CPI SF集成-组织集成(一)

将员工主数据和组织数据从SAP Successfactors Employee CentraI复制到SAPERP或SAP S/4HANA,SAP SF CPI HCM集成

SAP CPI 130

innovus:像ICC2一样设置placement label

ICC2有placement label/placement rule功能,能控制各种类型cell 之间的spacing规则,包括top和bottom edge的spacing。innovus也有相同的功能,以下示例方便大家了解用法。我们需要给所有OAI* cell之间设置一个spacing rule,让他们不要上下或者挨着。效果如下图,这个spacing指的是同一边的间距,不是cell间距。我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧?

m0_61544122的博客 836

LINUX平台高级调试和优化(上海站)

2023LINUXSHANGHAI软件调试高级研习班2023上海站LINUX平台高级调试与优化关于LINUX的资料浩如烟海,学习LINUX的途径也有很多,如何才能在比较短的时间里获得一个比较大的提升呢?《软件调试高级研习班2023上海站》将与各位LINUX爱好者共同探索这个问题的最佳答案。本着生动有趣、理论与实践密切结合的原则,本研习班独辟蹊径,采用封闭训练方式打造独有的沉浸式学习体验;使用调试之...

advdbgger的博客 216

IgH EtherCAT 从入门到精通:第 30 章 实战:高可用 EtherCAT 系统设计

摘要:构建高可用EtherCAT系统的关键技术 本章详细介绍了工业级EtherCAT系统的高可用性设计方法,主要包括: 冗余链路架构:采用双网卡环形拓扑设计,主备网卡同时工作,通过IgH Master的冗余配置实现线缆故障自动切换。 状态监控机制:提供专用API实时监控主备链路状态,包括从站响应数、链路状态和冗余激活标志,形成完整的故障判断矩阵。 自动恢复功能:系统内置FSM架构支持热插拔自动检测和重配置,从站断线/重连时可自动完成状态恢复,同时允许应用层实施安全措施。 这些技术共同构成了生产环境下Ethe

从事嵌入式linux android驱动开发,拥有全栈能力 247

LINUX平台高级调试和优化(2018上海站)

  关于LINUX的资料浩如烟海,学习LINUX的途径也有很多,如何才能在比较短的时间里获得一个比较大的提升呢?《软件调试高级研习班》将与各位LINUX爱好者共同探索这个...

格友 1008

零基础实战:用 Docker 和 vLLM 本地部署 bge-reranker-v2-m3 重排序模型

本文介绍了如何利用Docker容器和vLLM推理框架在本地部署BAAI开发的bge-reranker-v2-m3文本排序模型。

举世誉之而不加劝,举世非之而不加沮,定乎内外之分,辩乎荣辱之境,斯已矣。 5972

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Ubuntu内核升级:GitHub Actions runner-images系统稳定性优化

在持续集成/持续部署(CI/CD)的世界里,系统稳定性是保障开发效率的基石。作为GitHub官方维护的核心基础设施,runner-images项目提供的Ubuntu镜像承载着数百万开发者的自动化任务。然而,内核版本过旧导致的系统级问题——从容器网络异常到硬件驱动冲突,正成为影响工作流可靠性的关键瓶颈。本文将深入剖析Ubuntu内核升级的技术路径,通过对比GitHub Actions runner-...

gitblog_00509的博客 960

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Rocky Linux 8 下用 Certbot 为 Nginx 配置 Let‘s Encrypt SSL 实操指南

HTTPS 是现代 Web 服务的安全基石,其核心依赖于受信任的数字证书与自动化部署机制。Let’s Encrypt 作为免费、开放、自动化的证书颁发机构,通过 ACME 协议实现域名验证与证书生命周期管理;certbot 则是与其深度集成的官方客户端工具,尤其在 Rocky Linux 8 等 RHEL 系衍生系统中,依托 EPEL 仓库、systemd 定时器、SELinux 兼容策略和 Nginx 插件,提供了开箱即用的 HTTPS 实现路径。该方案规避了自签名证书的信任缺失问题,也优于商业证书的手动

weixin_32288959的博客 284

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

brpc IO 机制深度解析:从事件分发、无锁写队列到 Socket 生命周期管理

brpc 是一个工业级 C++ RPC 框架,其高性能的秘密很大程度上藏在 IO 层的设计里。本文以 [docs/en/io.md](https://link.gitcode.com/i/565b9fb186e98b01d8eade6a7a8bae37) 为核心骨架,深入剖析 brpc 的三大 IO 支柱:基于边缘触发 epoll 的事件分发(EDISP)、基于 wait-free MPSC 链表

gitblog_00809的博客 410
上一篇: 2017年企业运维经典面试题汇总
下一篇: 两张图学会VIM编辑器
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值