学习操作系统原理最好的方法是自己写一个简单的操作系统。
写程序不免需要调试,写不同的程序调试方式也不同。如果做应用软件开发,相应的程序调试方式是建立在有操作系统支持的基础上的。而我们现在是要开发操作系统,如何调试操作系统的程序呢?如果操作系统程序直接跑在真机上或虚拟机上(比如VirtualBox)是很难调试的,所以我们在开发阶段操作系统程序主要在虚拟机QEMU上跑,因为QEMU支持调试。当然很多事情都是有利也有弊的,QEMU虽然支持调试,但它的运行效率比VitrualBox要低,所以我们最终的GrapeOS程序是跑在VirtalBox上的。QEMU需要结合GDB才能实现调试,下面我们一起来学习一下。
在Windows的cmd命令行中输入如下一行命令:
qemu-system-i386 d:\GrapeOS\VMShare\GrapeOS.img -S -s
上面这行命令比之前多了两个参数,“-S”表示让CPU在将要执行第一条指令前暂停,“-s”表示让QEMU打开自带的GDB服务端功能,且网络端口号是1234。截图如下:

执行上面的命令后,会弹出QEMU的窗口:

从上图中可以看到QEMU窗口中间显示一行文字“Guest has not initialized the display(yet).”,此时QEMU已进入调试模式。当QEMU进入调试模式后,就在等待GDB客户端来连接它。当GDB客户端连接上QEMU的GDB服务端就可以调试了。就像我们用PowerShell连接到CentOS就可以在PowerShell中操纵CentOS一样,此时PowerShell是客户端,CentOS是服务端。下面我们来介绍GDB客户端。
GDB分为服务端和客户端,单说GDB,一般是指GDB客户端。GDB是Linux中的一个调试软件,所以我们准备在CentOS中使用它。首先我们通过PowerShell登录CentOS。
首次使用GDB可能需要安装一下:
yum install gdb
敲命令gdb就运行了,如下图:

在GDB中输入如下命令连接QEMU:
target remote 192.168.10.102:1234
上面这行命令中的IP地址“192.168.10.102”是我的Windows的IP地址,你需要替换成你的Windows的IP地址。截图如下:

如上截图所示,我们已经通过GDB连接到QEMU了。图中倒数第二行的十六进制数“0x0000fff0”表示CPU将要执行的指令地址。还记得前面介绍的实模式下1M内存的布局吗?这个地址在BIOS中,是CPU执行的第一条指令所在的地址。
设置断点是调试必备的一个功能,比如我们在0x7c00处设置个断点:
b *0x7c00

这样就设置好了一个断点。可以用同样的方式设置多个断点。
这个命令简单,只有一个字母“c”,然后回车即可让CPU继续运行,当遇到断点时会自动暂停。截图如下:

查看所有寄存器的命令是i r,截图如下:

从上图中可以看到此时CPU中很多寄存器的值,有朋友可能会有个疑问,以前学的寄存器是“ax、bx、cx……”这些,上面截图中怎么是“eax、ebx、ecx……”呢?原因是当年8086CPU的寄存器都是16位的,也就是“ax、bx、cx……”这些,很多讲x86汇编语言的资料都只讲了8086下的情况。而我们现在启动的是32位x86模拟器“qemu-system-i386”,所有通用寄存器多了一个字母“e”表示扩展,从16位扩展成了32位。这些32位通用寄存器中的低16位就是原来的16位寄存器,比如eax的低16位还是ax,ah和al仍然表示ax的高8位和低8位,其它寄存器也一样。这就是兼容,能让旧程序在新CPU上运行。之前的16位寄存器中只有段寄存器没有扩展,还是16位的,而且还增加了2个,分别是fs和gs。增加的这2个段寄存器作用和es基本一样,之所以增加是怕在复杂的程序中出现段寄存器不够用的情况。当数据比较多的时候GDB一般只输出一部分,此时如果按回车键还会显示出其它一些寄存器,但我们用不上,按“q”键退出继续输出即可。
下面来看一下如何查看单个寄存器,比如我们要查看寄存器ax的值,输入命令p $ax,如果想以十六进制显示可以输入命令p /x $ax,截图如下:

命令格式:x /nfu addr
n表示数量
f表示格式:x(hex), d(decimal), c(char)等。
u表示显示单位:b(byte), h(halfword), w(word), g(giant, 8 bytes)。
下面我们分别演示查看0x7c00开始的8个单字节、8个双字节、8个四字节、8个八字节的内存值。截图如下:

虽然目前看到的数据都是0,但我们以后写上程序就不一样了。
有时候需要将机器码反汇编成汇编代码方便查看,下面我们以反汇编0x7c00开始的10个字节为例:
disas 0x7c00,+10
截图如下:

上面截图中显示的汇编代码是GDB默认的AT&T语法,我们可以设置改成Intel语法:
set disassembly-flavor intel
截图如下:

需要说明一下的是这里的反汇编结果是错的。因为它是按照32位模式反汇编的,而我们现在还处在16位实模式中,所以这个反汇编功能只能等后面我们进入32位模式才有用。至于反汇编16位代码我们会在后续教程中介绍其它方法。
在调试的时候有时需要一条指令一条指令的单步执行,单步执行的命令是si。

从上面的截图可以看到,每输入一个si回车,就会执行一条命令。每个si命令下面一行中的十六进制数表示下一条指令的地址,可以看到地址在不断增加,说明的确在执行指令。如果想知道每一步都执行了什么指令,可以用下面这个命令来反汇编下一条要执行的指令:
set disassemble-next-line on

从上面截图中可以看到每一步的指令,但这个反汇编结果也是错的,原因和上面的一样。
顺便介绍个小技巧,如果不输入命令直接回车会重复上一个GDB命令,就像上图中最后两步,什么命令都没有直接回车就表示重复执行si这个GDB命令。
本讲最后介绍的指令是退出GDB,非常简单,输入q,然后再输入y即可。 截图如下:

退出GDB后就又回到进入GDB前的Linux命令行环境中了。
如果大家按照上面顺序做实验,退出GDB后,CPU占用率会比较高,和上讲中的情况一样,直接关闭QEMU窗口即可。这个问题我们在下一讲中解决。
本讲视频版地址:https://www.bilibili.com/video/BV18G4y1P7CU/
本教程代码和资料:https://gitee.com/jackchengyujia/grapeos-course
GrapeOS操作系统QQ群:643474045
这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/
我有一个使用SeleniumWebdriver和Nokogiri的Ruby应用程序。我想选择一个类,然后对于那个类对应的每个div,我想根据div的内容执行一个Action。例如,我正在解析以下页面:https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=puppies这是一个搜索结果页面,我正在寻找描述中包含“Adoption”一词的第一个结果。因此机器人应该寻找带有className:"result"的div,对于每个检查它的.descriptiondiv是否包含单词“adoption
我正在我的Rails项目中安装Grape以构建RESTfulAPI。现在一些端点的操作需要身份验证,而另一些则不需要身份验证。例如,我有users端点,看起来像这样:moduleBackendmoduleV1classUsers现在如您所见,除了password/forget之外的所有操作都需要用户登录/验证。创建一个新的端点也没有意义,比如passwords并且只是删除password/forget从逻辑上讲,这个端点应该与用户资源。问题是Grapebefore过滤器没有像except,only这样的选项,我可以在其中说对某些操作应用过滤器。您通常如何干净利落地处理这种情况?
在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.
a=[3,4,7,8,3]b=[5,3,6,8,3]假设数组长度相同,是否有办法使用each或其他一些惯用方法从两个数组的每个元素中获取结果?不使用计数器?例如获取每个元素的乘积:[15,12,42,64,9](0..a.count-1).eachdo|i|太丑了...ruby1.9.3 最佳答案 使用Array.zip怎么样?:>>a=[3,4,7,8,3]=>[3,4,7,8,3]>>b=[5,3,6,8,3]=>[5,3,6,8,3]>>c=[]=>[]>>a.zip(b)do|i,j|c[[3,5],[4,3],[7,6],
我有一个非常简单的Controller来管理我的Rails应用程序中的静态页面:classPagesController我怎样才能让View模板返回它自己的名字,这样我就可以做这样的事情:#pricing.html.erb#-->"Pricing"感谢您的帮助。 最佳答案 4.3RoutingParametersTheparamshashwillalwayscontainthe:controllerand:actionkeys,butyoushouldusethemethodscontroller_nameandaction_nam
是否有self验证的问题列表。看着那个,我可以确定我知道。我应该复习一下。在学习的过程中,我列了一个这样的list,但它只包含我在某处听说过的项目。我需要一段时间才能找到新的东西。 最佳答案 以下是针对ruby和Rails的一些测试列表。证书名称:RubyonRails谁提供:oDeskIncorporation认证费用:免费网站:https://www.odesk.com/tests/985?pos=0证书名称:RubyonRails提供者:Techgig.com(TimesBusinessSolutionsLimited(T
深度学习12.CNN经典网络VGG16一、简介1.VGG来源2.VGG分类3.不同模型的参数数量4.3x3卷积核的好处5.关于学习率调度6.批归一化二、VGG16层分析1.层划分2.参数展开过程图解3.参数传递示例4.VGG16各层参数数量三、代码分析1.VGG16模型定义2.训练3.测试一、简介1.VGG来源VGG(VisualGeometryGroup)是一个视觉几何组在2014年提出的深度卷积神经网络架构。VGG在2014年ImageNet图像分类竞赛亚军,定位竞赛冠军;VGG网络采用连续的小卷积核(3x3)和池化层构建深度神经网络,网络深度可以达到16层或19层,其中VGG16和VGG
1、接口请求基本操作1.1例子tips在view的选项可以zoomin调整窗口字帖大小。1、创建一个测试的workspace,并命名为test2、test后面新增一个addrequest3、选择发送GET,URL为一个开源的https://api.apiopen.top/api/sentences获取每日一句4、点击send查看内容Tips:如果提示出现Error:tunnelingsocketcouldnotbeestablished,statusCode=407错误,参照以下解决办法)关于tunnelingsocketcouldnotbeestablished,cause=getaddri
Linux操作系统——网络配置与SSH远程安装完VMware与系统后,需要进行网络配置。第一个目标为进行SSH连接,可以从本机到VMware进行文件传送,首先需要进行网络配置。1.下载远程软件首先需要先下载安装一款远程软件:FinalShell或者xhell7FinalShellxhell7FinalShell下载:Windows下载http://www.hostbuf.com/downloads/finalshell_install.exemacOS下载http://www.hostbuf.com/downloads/finalshell_install.pkg2.配置CentOS网络安装好