2 分析第一个OS

本文详细解析了使用BOCHS加载操作系统时,寄存器的初始状态及指令执行过程中的变化,包括设置断点、查看寄存器信息等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前面我成功加载了第一个OS,下面我将重点分析bochs加载OS时,寄存器都做了什么?


在使用选项6启动bochs的时候,在终端输入:<bochs:1>b 0x7c00,它表示在07c000地址处设置断点,因为引导扇区是从这里开始的。然后继续输入:<bochs:2>c,表示继续执行指令。完成这两条命令,将会看到终端命令窗口显示如下信息。


Nextat t=0

(0)[0x00000000fffffff0] f000:fff0 (unk. ctxt): jmp far f000:e05b ; ea5be000f0

<bochs:1>b 0x7c00

<bochs:2>c

00000003305i[BIOS] $Revision: 1.247 $ $Date: 2010/04/04 19:33:50 $

00000318057i[KBD ] reset-disable command received

00000442371i[VBIOS]VGABios $Id$

00000442442i[VGA ] VBE known Display Interface b0c0

00000442474i[VGA ] VBE known Display Interface b0c5

00000443143i[VBIOS]VBE Bios $Id$

00000600000i[XGUI] charmap update. Font Height is 16

00000760659i[BIOS] Starting rombios32

00000761138i[BIOS] Shutdown flag 0

00000761777i[BIOS] ram_size=0x02000000

00000762239i[BIOS] ram_end=32MB

00000802861i[BIOS] Found 1 cpu(s)

00000819037i[BIOS] bios_table_addr: 0x000fbc18 end=0x000fcc00

00000831660i[BIOS] bios_table_cur_addr: 0x000fbc18

00012943044i[BIOS] Booting from 0000:7c00

(0)Breakpoint 1, 0x00007c00 in ?? ()

Nextat t=12943105

(0)[0x0000000000007c00] 0000:7c00 (unk. ctxt): mov ax, cs ; 8cc8

<bochs:3>


可以看到,当我们在0x7c00设置断点时,代码执行到此处将会停止。同时终端命令窗口还显示了下一条命令,如:


(0)[0x0000000000007c00] 0000:7c00 (unk. ctxt): mov ax, cs ; 8cc8


注意[0x0000000000007c00],表示指令的地址,即加载程序的地方(还记得org07c00h吗?)。此时,可以输入命令,查看寄存器信息。(在《Orange's...》中使用dump_cpu,这个命令在bochs2.3.5以上版本中没有)


<bochs:3>info cpu

eax:0x0000aa55 43605

ecx:0x00090000 589824

edx:0x00000000 0

ebx:0x00000000 0

esp:0x0000ffd6 65494

ebp:0x00000000 0

esi:0x000e478c 935820

edi:0x0000ffac 65452

eip:0x00007c00

eflags0x00000082: id vip vif ac vm rf nt IOPL=0 of df if tf


可以看到eip指向0x7c00,表示执行从这个地方开始。这也是为什么代码清单要是用:org07c00h


<bochs:4>sreg

es:0x0000,dh=0x00009300, dl=0x0000ffff, valid=1

Datasegment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessed

cs:0x0000,dh=0x00009300, dl=0x0000ffff, valid=1

Datasegment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessed

ss:0x0000,dh=0x00009300, dl=0x0000ffff, valid=7

Datasegment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessed

ds:0x0000,dh=0x00009300, dl=0x0000ffff, valid=1

Datasegment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessed

fs:0x0000,dh=0x00009300, dl=0x0000ffff, valid=1

Datasegment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessed

gs:0x0000,dh=0x00009300, dl=0x0000ffff, valid=1

Datasegment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessed

ldtr:0x0000,dh=0x00008200, dl=0x0000ffff, valid=1

tr:0x0000,dh=0x00008b00, dl=0x0000ffff, valid=1

gdtr:base=0x000fb997,limit=0x30

idtr:base=0x00000000,limit=0x3ff


此时段寄存器csesdsgs等都为0。执行下一条指令(执行我编写的代码),看看寄存器状态。


<bochs:5>n

Nextat t=12943102

(0)[0x0000000000007c02] 0000:7c02 (unk. ctxt): mov ds, ax ; 8ed8

<bochs:6>r

eax:0x00000000 0

ecx:0x00090000 589824

edx:0x00000000 0

ebx:0x00000000 0

esp:0x0000ffd6 65494

ebp:0x00000000 0

esi:0x000e478c 935820

edi:0x0000ffac 65452

eip:0x00007c02

eflags0x00000082: id vip vif ac vm rf nt IOPL=0 of df if tf SF z


可以看到粗体标识的地方为执行:movax cs后的改变情况。同时下一条指令地址变为:[0x0000000000007c02],表示mov指令占用2个地址。后面的2条指令将改变寄存器dses


<bochs:7>n

Nextat t=12943103

(0)[0x0000000000007c04] 0000:7c04 (unk. ctxt): mov es, ax ; 8ec0

……

<bochs:8>n

Nextat t=12943104

(0)[0x0000000000007c06] 0000:7c06 (unk. ctxt):call .+2 (0x00007c0b) ; e80200


此时下一条指令为:call.+2 (0x00007c0b),其中0x00007c0b表示要跳转的地址。继续执行,n将会跳出方法继续。方法中将会调用int 10中断在显示器上显示字符。


<bochs:9>n

Next at t=12954683

(0)[0x0000000000007c09]0000:7c09 (unk. ctxt): jmp .-2 (0x00007c09)


从这句可以看出$表示当前地址。


<bochs:10> n

Next at t=12954684

(0) [0x0000000000007c09] 0000:7c09(unk. ctxt): jmp .-2 (0x00007c09) ; ebfe


因为跳转地址为执行语句地址,所以陷入无限循环。

<think>嗯...用户这次提出了一个非常具体的网络故障排查问题,关于RouterOS设备中IPv6只能ping通第一个数据包的异常现象。从引用内容来看,用户可能已经查阅了NAT64、防火墙行为等资料,但核心诉求明确指向RouterOS的IPv6连通性故障。用户的技术背景应该比较扎实,能够精准描述"onlyfirstpacket"这种典型症状。这通常暗示着状态保持机制失效,比如防火墙状态跟踪异常或NDP缓存问题。考虑到RouterOS的特性,需要重点检查三个层面:IPv6邻居发现协议状态、firewall连接跟踪机制、以及RA路由通告的合法性。有趣的是引用1提到的NAT64虽然和IPv6相关,但用户实际网络环境更可能是纯IPv6通信,因为故障表现为ping而非协议转换失败。引用2的防火墙默认行为提示很关键,在RouterOS中未匹配策略的IPv6报文确实会被丢弃,不过第一次ping能通说明首包通过了策略,后续被阻断了,这更指向有状态防火墙的会话建立问题。从工程经验看,这类故障80%概率出在NDP或firewall规则,因此回复时需要优先指导用户:1.用"/ipv6neighborprint"命令确认ND缓存是否正常刷新2.检查firewallconnectiontracking的timeout值是否合理3.特别注意ICMPv6报文在filter规则中的处理方式用户没有提供具体拓扑信息,所以需要补充提问。另外要注意RouterOS的bug数据库记载过类似故障,6.40~6.43版本在bridge环境下有NDP缺陷,这个冷知识应该放进回答里。最后要保持故障排查的递进逻辑,先查基础配置再挖深层原因,毕竟用户可能正在紧急恢复业务。</think> 以下是针对 RouterOS 中 IPv6 仅能 Ping 通第一个包的故障排查步骤及解决方案: --- ### **故障原因分析** 1. **NDP缓存超时** IPv6 依赖 **NDP协议**(邻居发现协议)维护邻居表。若邻居表项刷新异常或超时时间过短,首包触发地址解析后,后续包因无有效表项被丢弃。 *典型表现*:第一个 ICMPv6 包正常,后续包超时。 2. **防火墙连接跟踪(Connection Tracking)失效** IPv6 需通过状态防火墙跟踪连接状态。若连接跟踪表未正确建立,或规则未允许已建立连接,将导致后续包被丢弃。 *检查命令*: ```bash /ipv6 firewall connection print # 查看连接跟踪状态 ``` 3. **路由/NDP代理配置错误** 若网络中存在 **NDP代理**(如 VLAN 间通信),配置错误可能导致邻居表无法刷新。 --- ### **排查与修复步骤** #### **步骤1:检查NDP邻居状态** ```bash /ipv6 neighbor print # 查看邻居表状态 ``` - ✅ **正常状态**:`REACHABLE`(可直达) - ❌ **故障状态**:`STALE`(失效)或 `INCOMPLETE`(解析失败) **修复方案**: ```bash /ipv6 settings set [find] reachable-time=30s # 缩短可到达时间(默认30秒) /ipv6 neighbor flush # 强制刷新邻居缓存 ``` #### **步骤2:验证防火墙规则** 检查 IPv6 防火墙是否正确处理 **已建立/相关连接**: ```bash /ipv6 firewall filter print # 查看过滤规则 ``` - **必须包含规则**: ```bash add chain=forward action=accept connection-state=established,related add chain=forward action=accept connection-state=new # 允许新连接首包 ``` - **排查点**: - 规则顺序错误(`established` 规则需在 `new` 之后) - 未配置 `related`(影响 ICMPv6 关联连接) #### **步骤3:关闭代理NDP(若存在)** ```bash /ipv6 settings set [find] disable-ra=yes # 禁用路由通告(RA) /ipv6 nd set [find] advertise-mac=yes # 启用MAC地址通告 ``` #### **步骤4:更新RouterOS版本** 若以上步骤无效,尝试升级至最新稳定版: ```bash /system package update install ``` *已知问题*:v6.43 之前版本存在 NDP 刷新 Bug[^1]。 --- ### **验证方法** 使用连续 Ping 测试(间隔 <1 秒): ```bash ping -6 -i 0.5 2001:db8::1 # Linux ping -6 -t 500 2001:db8::1 # Windows(-t 持续ping,-i 间隔) ``` ✅ **修复成功**:连续收到回复 ❌ **失败**:仅首包通,后续包超时 --- ### **附:防火墙规则模板** ```bash /ipv6 firewall filter add chain=forward action=accept protocol=icmpv6 # 允许ICMPv6 add chain=forward action=accept connection-state=established,related # 放行已建立连接 add chain=forward action=accept connection-state=new # 放行新连接首包 add chain=forward action=drop # 默认丢弃其他流量 ``` > **注意**:若网络复杂(如 VLAN/PPPoE),需额外检查接口绑定和路由宣告配置。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值