当前位置: 首页 > news >正文

photoshop制作网站海报sem推广代运营

photoshop制作网站海报,sem推广代运营,网络服务提供者不是网络运营者对不对,我要外包网官网1中断是什么既然叫中断, 那我们首先就会想到这个中断是中断谁#xff1f;想一想计算机最核心的部分是什么#xff1f;没错#xff0c; CPU#xff0c; 计算机上绝大部分的计算都在CPU中完成#xff0c;因此这个中断也就是中断CPU当前的运行#xff0c;让CPU转而先处理这个… 1中断是什么既然叫中断, 那我们首先就会想到这个中断是中断谁想一想计算机最核心的部分是什么没错 CPU 计算机上绝大部分的计算都在CPU中完成因此这个中断也就是中断CPU当前的运行让CPU转而先处理这个引起中断的事件通常来说这个中断的事件比较紧急处理完毕后再继续执行之前被中断的task。比如我们敲击键盘CPU就必须立即响应这个操作不然我们打字就全变成了慢动作说白了中断其实就是一种主动通知机制如果中断源不主动通知那想知道其发生了什么事情只能一次次地轮询了白白耗费CPU。2中断的分类大的方向上一般分为两大类同步中断和异步中断按Intel的说法将异步中断称为中断将同步中断称为异常。异步中断主要是指由CPU以外的硬件产生的中断比如鼠标键盘等。它的特点是相对CPU来说随时随机发生事先完全没有预兆不可预期的。异步中断发生时CPU基本上都正在执行某条指令。异步中断可分为可屏蔽和不可屏蔽两种字如其义不用多解释。同步中断主要是指由CPU在执行命令过程中产生的异常它一定是在CPU执行完一条命令后才会发出产生于CPU内部。按其被CPU处理后返回位置的不同我们将同步中断分为故障(fault), 陷阱(trap)和终止(abort)三类。我们通过一个表格来作下对比区分两点说明处理完毕后的返回位置发生异常时CPU最终会进入到相应的异常处理程序中(简单说就是CPU需要执行一次跳转)在执行具体操作前会设置好的异常处理完成后跳转回的CS:IP, 即代码段寄存器和程序指针寄存器不同类型的异常其设置的CS:IP不同而已有些分类方法还会有一种叫可编程异常的比如说把系统调用算作这一类也可以。但是如果按处理完毕后的返回位置来说系统调用是可以归入陷阱这一类的。3面对如此众多的服务器我们都知道CPU上只有有限多的脚针负责与外部通讯比如有数据线地址线等也有中断线但一般只有两条NMI(不可屏蔽中断线)和INTR(可屏蔽中断线) 新的CPU有LINT0和LINT1脚针。那您会问了电脑上有那么多外设CPU就这两根线怎么接收这么多外设的中断信号呢确实因此CPU找了一个管理这些众多中断的代理人——中断控制器。就目前我们使用的SMP多核架构里我们经常使用高级可编程中断控制器APIC 老式的 8259A 可编程中断控制器大家有兴趣可自行搜索。APIC分为两部分IO APIC和Local APIC从名字上我们就可略知一二。IO APIC: 用来连接各种外设的硬件控制器接收其发送的中断请求信号然后将其传送到Local APIC, 这个IO APIC一般会封装在主板南板芯片上;Local APIC: 基本上集成在了CPU里 向CPU通知中断发生。放张网上的图4中断的初始化Linux的启动流程中断的初始化是穿插在Linux本身启动和初始化过程中的因此我们在这里简要说一下Linux本身的初始化。64位Linux启动大的方向上需要经过 实模式 - 保护模式 - 长模式 第三种模式的转换;电源接通CPU启动并重置各寄存器后运行于实模式下CS:IP加载存储于ROM中的一跳转指令跳转到BIOS中BIOS启动硬件自测读取MRB;BIOS运行第一阶段引导程序第一阶段引导程序运行第二阶段引导程序通常是 grub;Grub开始引导内核运行;相关初始化后进行保护模式再进入长模式内核解压缩体系无关初始化部分;体系相关初始化部分;总结了一张图仅供参考中断描述符表外设千万种CPU统统不知道。所有的中断到了CPU这里就只是一个中断号然后初始化阶段设置好中断号到中断处理程序的对应关系CPU获取到一个中断号后查到对应的中断处理程序调用就好了。这两者的对应关系最后会抽象成了中断向量表 现在叫 IDT中断描述符表。中断的第一次初始化实模式下的初始化上面那张Linux启动流程图如果你仔细看的话会发现在BIOS程序加载运行时在实模式下也有一个BIOS的中断向量表这个中断向量表提供了一些类似于BIOS的系统调用一样的方法。比如Linux在初始化时需要获取物理内存的详情就 是调用了BIOS的相应中断来获取的。见下图中断的第二次初始化在进入到保护模式后会全新初始化一个空的中断描述符表 IDT, 供 kernel 使用;Linux Kernel提供256个大小的中断描述符表#define IDT_ENTRIES 256gate_desc idt_table[IDT_ENTRIES] __page_aligned_bss;中断的第三次初始化在进入到长模式后在x86_64_start_kernel先初始化前32个异常类型的中断(即上面定义的 idt_table 的前32项)void __init idt_setup_early_handler(void){ int i; for (i 0; i NUM_EXCEPTION_VECTORS; i) set_intr_gate(i, early_idt_handler_array[i]); load_idt(idt_descr);}其中 early_idt_handler_array这个数组放置了32个异常类型的中断处理程序我们先看一下它的定义const char early_idt_handler_array[32][9];二维数组每一个early_idt_handler_array[i]有9个字节。这个 early_idt_handler_array的初始化很有意思它用ATT的汇编代码完成在文件arch/x86/kernel/head_64.S中ENTRY(early_idt_handler_array) i 0 .rept NUM_EXCEPTION_VECTORS .if ((EXCEPTION_ERRCODE_MASK i) 1) 0 UNWIND_HINT_IRET_REGS pushq $0 # Dummy error code, to make stack frame uniform .else UNWIND_HINT_IRET_REGS offset8 .endif pushq $i # 72(%rsp) Vector number jmp early_idt_handler_common UNWIND_HINT_IRET_REGS i i 1 .fill early_idt_handler_array i*EARLY_IDT_HANDLER_SIZE - ., 1, 0xcc .endr UNWIND_HINT_IRET_REGS offset16END(early_idt_handler_array)这段汇编循环遍历32次来初始化每一个early_idt_handler_array[i], 也就是填充它的9个字节其中2个字节是压栈错误码指令2个字节是压栈向量号指令余下的5个字节是函数跳转指令(jmp early_idt_handler_common)。由此我们可以看出这前32个异常类型的中断处理函数最终都会调用到early_idt_handler_common, 这个函数这里就不贴它的代码了我们说下它的大致流程a. 先将各寄存器的值压栈保存b. 如果是 缺页异常就调用 early_make_patable; c. 如果是 其他异常就调用 early_fixup_exception;体系结构相关的中断初始化:这也是一次部分初始化它发生在 start_kernel的setup_arch中即发生在 Linux 启动流程中的体系结构初始化部分。这部分实际上是更新上面已初始化的32个异常类中的X86_TRAP_DB(1号, 用于debug)和X86_TRAP_BP(3号, 用于debug时的断点);static const __initconst struct idt_data early_idts[] { INTG(X86_TRAP_DB, debug), SYSG(X86_TRAP_BP, int3),};void __init idt_setup_early_traps(void){ idt_setup_from_table(idt_table, early_idts, ARRAY_SIZE(early_idts), true); load_idt(idt_descr);}debug和int3这两个汇编实现的中断处理程序这里我们就不详述了。更新 X86_TRAP_PF 缺页异常的中断处理程序void __init idt_setup_early_pf(void){ idt_setup_from_table(idt_table, early_pf_idts, ARRAY_SIZE(early_pf_idts), true);}static const __initconst struct idt_data early_pf_idts[] { INTG(X86_TRAP_PF, page_fault),};在trap_init中调用 idt_setup_traps更新部分异常的中断处理程序void __init idt_setup_traps(void){ idt_setup_from_table(idt_table, def_idts, ARRAY_SIZE(def_idts), true);}static const __initconst struct idt_data def_idts[] { INTG(X86_TRAP_DE, divide_error), INTG(X86_TRAP_NMI, nmi), INTG(X86_TRAP_BR, bounds), INTG(X86_TRAP_UD, invalid_op), INTG(X86_TRAP_NM, device_not_available), INTG(X86_TRAP_OLD_MF, coprocessor_segment_overrun), INTG(X86_TRAP_TS, invalid_TSS), INTG(X86_TRAP_NP, segment_not_present), INTG(X86_TRAP_SS, stack_segment), INTG(X86_TRAP_GP, general_protection), INTG(X86_TRAP_SPURIOUS, spurious_interrupt_bug), INTG(X86_TRAP_MF, coprocessor_error), INTG(X86_TRAP_AC, alignment_check), INTG(X86_TRAP_XF, simd_coprocessor_error),#ifdef CONFIG_X86_32 TSKG(X86_TRAP_DF, GDT_ENTRY_DOUBLEFAULT_TSS),#else INTG(X86_TRAP_DF, double_fault),#endif INTG(X86_TRAP_DB, debug),#ifdef CONFIG_X86_MCE INTG(X86_TRAP_MC, machine_check),#endif SYSG(X86_TRAP_OF, overflow),#if defined(CONFIG_IA32_EMULATION) SYSG(IA32_SYSCALL_VECTOR, entry_INT80_compat),#elif defined(CONFIG_X86_32) SYSG(IA32_SYSCALL_VECTOR, entry_INT80_32),#endif};在trap_init中调用 idt_setup_ist_traps更新部分异常的中断处理程序看到这里您可能问上面不是调用了idt_setup_traps怎么这时又调用idt_setup_ist_traps? 这两者有什么区别说起来话有点长我们尽量从流程上给大家讲清楚但不深入到具体的细节。想说明这个问题我们先来讲下栈这个东西:a.  首先每个进程都有自己的用户态栈对应进程虚拟地址空间内的stack部分用于进程在用户态变量申请函数调用等操作b. 除了用户态栈每个进程在创建时(内核对应创建 task_struct结构)同时会创建对应的内核栈这里进程由用户态进入到内核态执行函数时相应的所用的栈也会切换到内核栈c. 如果内核进入到中断处理程序早期的kernel针对中断处理程序的执行会使用当前中断task的内核栈这里有存在一定的问题存在栈溢出的风险。举个例子如果在中断处理程序里又发生了异常中断此时会触发double fault但其在处理过程中依然要使用当前task的内核栈并且当前task内核栈已满double fault无法被正确处理。为了解决这样的内部linux kernel引出了独立的内核栈针对SMP系统它还是pre-cpu的。我们来看一下其初始化,还特别贴心地为softirq也开辟了单独的栈:void irq_ctx_init(int cpu){ union irq_ctx *irqctx; if (hardirq_ctx[cpu]) return; // 硬中断独立栈 irqctx (union irq_ctx *)hardirq_stack[cpu * THREAD_SIZE]; irqctx-tinfo.task NULL; irqctx-tinfo.cpu cpu; irqctx-tinfo.preempt_count HARDIRQ_OFFSET; irqctx-tinfo.addr_limit MAKE_MM_SEG(0); hardirq_ctx[cpu] irqctx; //软中断独立栈 irqctx (union irq_ctx *)softirq_stack[cpu * THREAD_SIZE]; irqctx-tinfo.task NULL; irqctx-tinfo.cpu cpu; irqctx-tinfo.preempt_count 0; irqctx-tinfo.addr_limit MAKE_MM_SEG(0); softirq_ctx[cpu] irqctx; printk(CPU %u irqstacks, hard%p soft%p\n, cpu, hardirq_ctx[cpu], softirq_ctx[cpu]);}2. 在x86_64位系统中还引入了一种新的栈配置IST(Interrupt Stack Table)。目前Linux kernel中每个cpu最多支持7个IST可以通过tss.ist[]来访问。3. 现在我们再来看idt_setup_ist_traps其实就是重新初始化一个异常处理让这些异常处理使用IST作为中断栈。其中 IST_INDEX_DB IST_INDEX_NMI IST_INDEX_DF IST_INDEX_MCE就是要使用的ist[]的索引。void __init idt_setup_ist_traps(void){ idt_setup_from_table(idt_table, ist_idts, ARRAY_SIZE(ist_idts), true);}static const __initconst struct idt_data ist_idts[] { ISTG(X86_TRAP_DB, debug, IST_INDEX_DB), ISTG(X86_TRAP_NMI, nmi, IST_INDEX_NMI), ISTG(X86_TRAP_DF, double_fault, IST_INDEX_DF),#ifdef CONFIG_X86_MCE ISTG(X86_TRAP_MC, machine_check, IST_INDEX_MCE),#endif};#define ISTG(_vector, _addr, _ist) \ G(_vector, _addr, _ist 1, GATE_INTERRUPT, DPL0, __KERNEL_CS)剩下的最后一部分就是硬件中断的初始化了它同样在start_kernel中执行early_irq_init();init_IRQ();这部分具体细节我们在Linux中断一网打尽(2) - IDT及中断处理的实现介绍。本文转载自云计算往期精彩回顾2019年度精选文章httprunner使用总结全国新型肺炎实时动态360技术公众号技术干货|一手资讯|精彩活动扫码关注我们
http://www.sadfv.cn/news/42405/

相关文章:

  • icp主体备案号 网站备案号哪个网站做恒指好
  • 三水建设网站比较成功的网络营销案例
  • 广州网站优化电话wap网站用什么开发
  • 能自己做照片书的有哪些网站wordpress 首页分页
  • 云主机 网站指南wordpress 主页修改
  • 郑州市网站和公众号建设河北移动端网站建设
  • seo做的不好的网站有哪些迁西网站开发
  • 课程资源网站开发菲律宾有做网站的吗
  • 建设外贸购物网站海外推广公司
  • 网站建设 后期维护网站网格设计
  • 网站的可视化设计wordpress d8 4.1
  • 贵阳建设厅网站小程序代理好做吗
  • iis 子网站网站站外优化
  • 举报网站建设公司网站建设项目需求分析流程图
  • c#网站购物车怎么做贵溪网站建设
  • 网站怎么认证phpcms网站模板
  • 泰州商城网站开发校园门户网站系统建设关键技术
  • 登陆不了建设银行网站wordpress没有php.ini
  • wordpress做网站优点Asp做网站前期准备
  • 学校网站建设开题报告书软件开发模型包括
  • 广告公司管理软件wordpress 后台速度优化
  • 网站关键词和描述黄冈网站推广平台
  • 移动端网站模板海外网站建设
  • 大型行业门户网站开发建设怎么自己制作个网站
  • 网站开发报酬面试个人简历范文及网站建设
  • 做展柜在哪些网站找客户单位建设网站用交印花税吗
  • php源码网站后台面密码忘了在哪能找回密码2022网页游戏排行榜前十名
  • 计算机应用技术网站开发templatepath wordpress
  • 网站模版是什么意思wordpress能采集
  • wordpress给导航添加图片直通车优化推广