GXemul-note

GXemul-note

Charles Lv7

转载声明:本笔记转载自北航OS官方教程:GXemul模拟器

GXemul 模拟器介绍

GXemul(Gavare’s eXperimental Emulator)是一款计算机架构模拟器,可以模拟所需硬件环境,例如本实验需要的 MIPS 架构下的 CPU。尽管模拟器的开发仍在进行中,但自 2004 年以来,它已经足够稳定,可以让各种未经修改的操作系统运行就好像它们在真正的硬件上运行一样。目前模拟的处理器架构包括 ARM,MIPS,Motorola 88K,PowerPC 等。 经验证可在模拟器内工作的操作系统是 NetBSD,Linux,HelenOS,Ultrix 和 Sprite。

除了运行整个操作系统外,还可以使用模拟器用于较小规模的实验,例如爱好者们的操作系统开发等等。

GXemul 的基本工作方式

GXemul 的动态翻译器通常从模拟架构的汇编代码表示(例如 MIPS)转换成一种中间表示(IR),然后转换成可由本机执行的原生汇编代码(通常为 x86_64 或 x86 架构的代码,例如我们的跳板机为 x86_64 架构)。由于 GXemul 的主要目标之一是尽可能地保持所有内容的可移植性,因此 GXemul 的 IR 无论最终步骤(从 IR 到本机代码的转换)是否已实现,都能确保可以被执行。

这部分并不是课程要求掌握的内容,有兴趣的同学可自行参考GXemul: Dynamic Translation Internals

GXemul 的基本使用

GXemul 是我们运行 MOS 操作系统的模拟器,它可以帮助我们运行和调试 MIPS 体系架构下的代码。直接输入

1
$ gxemul

会显示帮助信息。

运行 GXemul

GXemul 运行选项:

  • -E 模拟机器的类型
  • -C 模拟 CPU 的类型
  • -M 模拟的内存大小
  • -V 进入调试模式

假设我们通过编译得到了一个 MIPS 架构的可执行文件 hello,我们通过如下方式运行 hello

1
$ gxemul -E testmips -C R3000 -M 64 hello

我们还可以用如下命令以调试模式打开 GXemul,对 hello 进行调试(进入后直接中断,输入 continue 或 step 才会继续运行,在此之前可以进行添加断点等操作)

1
$ gxemul -E testmips -C R3000 -M 64 -V hello

上方命令中:-E testmips 表示模拟器类型为 MIPS 架构,-C R3000 表示模拟 CPU 类型为 MIPS R3000,-M 64 代表模拟的内存大小为 64Mb,-V 代表进入调试模式。

GXemul 模拟器的一些基本命令

进入 GXemul 后使用 Ctrl+C 可以中断运行。中断后可以进行单步调试,执行如下指令:

  • breakpoint add addr 添加断点
  • continue 继续执行
  • step [n] 向后执行 n 条汇编指令
  • lookup name|addr 通过名字或地址查找标识符
  • dump [addr [endaddr]] 查询指定地址的内容
  • reg [cpuid][,c] 查看寄存器内容,添加”,c”可以查看协处理器
  • help 显示各个指令的作用与用法
  • quit 退出

(以上中括号表示内容可以没有)

更多 GXemul 相关的信息参考: GXemul - Documentation

如何退出 GXemul

  • 按 Ctrl+C,以中断模拟器;
  • 输入 quit 以退出模拟器。

Warning

一定要区分好”退出模拟器“,和“把模拟器挂在后台”这两件事。模拟器是相当占用系统资源的。可能有同学不小心按下 ctrl+z 把模拟器挂到后台,或是不确定自己有没有把挂起的进程关掉,可以通过 ps -ef | grep gxemul 命令观察后台有多少正在运行的作业。如果发现有多个模拟器正在运行的话,可以使用 kill 命令直接杀死。也可以通过 pkill -9 gxemul,一步杀死后台运行的模拟器。同学们可以自行了解一下 Linux 后台进程管理的知识。


GXemul 实际调试

可以看到我们运行调试可执行文件,需要敲入较长的一条指令,但实验中已经将启动的 GXemul 的命令融进 Makefile 中了,当构建完成后下将产生可执行的文件,此时可通过下方指令运行:

1
$ make run

同时,可通过下方指令调试。

1
$ make dbg

另外,可通过下方指令加载用户程序的符号表,其中 user/fktest.b 是用户程序 .b 文件的路径。(预习实验中不需要该特性,正式课设实验中会提供该特性。)

1
$ make dbg prog=user/fktest.b

同时,可通过下方指令导出内核与所有用户程序 *.b 的反汇编。

1
$ make objdump

得到诸如 target/mos.objdump 的反汇编文件后,我们可以通过 vim 查看其内容,以 target/mos.objdump 为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
target/mos:     文件格式 elf32-tradlittlemips
target/mos


Disassembly of section .tlb_miss_entry:

80000000 <tlb_miss_entry>:
tlb_miss_entry():
/home/git/你的学号/kern/entry.S:6
80000000: 08000020 j 80000080 <exc_gen_entry>
80000004: 00000000 nop

Disassembly of section .exc_gen_entry:

80000080 <exc_gen_entry>:
exc_gen_entry():
/home/git/你的学号/kern/entry.S:10
80000080: 03a0d025 move k0,sp
80000084: 07a00002 bltz sp,80000090 <exc_gen_entry+0x10>
80000088: 00000000 nop

...

800117f0 <strcmp>:
strcmp():
/home/git/你的学号/lib/string.c:83

int strcmp(const char *p, const char *q) {
800117f0: 27bdfff8 addiu sp,sp,-8
800117f4: afbe0004 sw s8,4(sp)
800117f8: 03a0f025 move s8,sp
800117fc: afc40008 sw a0,8(s8)
80011800: afc5000c sw a1,12(s8)
/home/git/你的学号/lib/string.c:84
while (*p && *p == *q) {
80011804: 10000009 b 8001182c <strcmp+0x3c>
80011808: 00000000 nop
/home/git/你的学号/lib/string.c:85
p++, q++;
8001180c: 8fc20008 lw v0,8(s8)
80011810: 00000000 nop
80011814: 24420001 addiu v0,v0,1
80011818: afc20008 sw v0,8(s8)
8001181c: 8fc2000c lw v0,12(s8)
80011820: 00000000 nop
80011824: 24420001 addiu v0,v0,1
80011828: afc2000c sw v0,12(s8)
/home/git/你的学号/lib/string.c:84
while (*p && *p == *q) {
8001182c: 8fc20008 lw v0,8(s8)
80011830: 00000000 nop
80011834: 80420000 lb v0,0(v0)
80011838: 00000000 nop
8001183c: 1040000a beqz v0,80011868 <strcmp+0x78>
80011840: 00000000 nop
/home/git/你的学号/lib/string.c:84 (discriminator 1)
80011844: 8fc20008 lw v0,8(s8)
80011848: 00000000 nop
8001184c: 80430000 lb v1,0(v0)
80011850: 8fc2000c lw v0,12(s8)
80011854: 00000000 nop
80011858: 80420000 lb v0,0(v0)
8001185c: 00000000 nop
80011860: 1062ffea beq v1,v0,8001180c <strcmp+0x1c>
80011864: 00000000 nop
/home/git/你的学号/lib/string.c:88
}

if ((u_int)*p < (u_int)*q) {
80011868: 8fc20008 lw v0,8(s8)
8001186c: 00000000 nop
80011870: 80420000 lb v0,0(v0)
80011874: 00000000 nop
80011878: 304300ff andi v1,v0,0xff
8001187c: 8fc2000c lw v0,12(s8)
80011880: 00000000 nop
80011884: 80420000 lb v0,0(v0)
80011888: 00000000 nop
8001188c: 304200ff andi v0,v0,0xff
80011890: 0062102b sltu v0,v1,v0
80011894: 10400004 beqz v0,800118a8 <strcmp+0xb8>
80011898: 00000000 nop
/home/git/你的学号/lib/string.c:89
return -1;
8001189c: 2402ffff li v0,-1
800118a0: 10000012 b 800118ec <strcmp+0xfc>
800118a4: 00000000 nop
/home/git/你的学号/lib/string.c:92
}

if ((u_int)*p > (u_int)*q) {
800118a8: 8fc20008 lw v0,8(s8)
800118ac: 00000000 nop
800118b0: 80420000 lb v0,0(v0)
800118b4: 00000000 nop
800118b8: 304300ff andi v1,v0,0xff
800118bc: 8fc2000c lw v0,12(s8)
800118c0: 00000000 nop
800118c4: 80420000 lb v0,0(v0)
800118c8: 00000000 nop
800118cc: 304200ff andi v0,v0,0xff
800118d0: 0043102b sltu v0,v0,v1
800118d4: 10400004 beqz v0,800118e8 <strcmp+0xf8>
800118d8: 00000000 nop
/home/git/你的学号/lib/string.c:93
return 1;
800118dc: 24020001 li v0,1
800118e0: 10000002 b 800118ec <strcmp+0xfc>
800118e4: 00000000 nop
/home/git/你的学号/lib/string.c:96
}

return 0;
800118e8: 00001025 move v0,zero
/home/git/你的学号/lib/string.c:97
}
800118ec: 03c0e825 move sp,s8
800118f0: 8fbe0004 lw s8,4(sp)
800118f4: 27bd0008 addiu sp,sp,8
800118f8: 03e00008 jr ra
800118fc: 00000000 nop

...

可以看到,上述 target/mos.objdump 中标出了目标文件汇编与每一行对应的源码,有助于我们进行调试。

Launch GXemul In DEBUG Mode

当我们以调试模式启动 GXemul 后,我们可以通过 help 查看 GXemul 内的可用指令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
GXemul> help
Available commands:
allsettings show all settings
breakpoint ... manipulate breakpoints
continue continue execution
device ... show info about (or manipulate) devices
dump [addr [endaddr]] dump memory contents in hex and ASCII
emuls print a summary of all current emuls
focus x[,y[,z]] changes focus to cpu x, machine x, emul z
help print this help message
itrace toggle instruction_trace on or off
lookup name|addr lookup a symbol by name or address
machine print a summary of the current machine
ninstrs [on|off] toggle (set or unset) show_nr_of_instructions
pause cpuid pause (or unpause) a CPU
print expr evaluate an expression without side-effects
put [b|h|w|d|q] addr, data modify emulated memory contents
quiet [on|off] toggle quiet_mode on or off
quit quit the emulator
reg [cpuid][,c] show GPRs (or coprocessor c's registers)
step [n] single-step one (or n) instruction(s)
tlbdump [cpuid][,r] dump TLB contents (add ',r' for raw data)
trace [on|off] toggle show_trace_tree on or off
unassemble [addr [endaddr]] dump memory contents as instructions
version print version information
x = expr generic assignment

In generic assignments, x must be a register or other writable settings
variable, and expr can contain registers/settings, numeric values, or symbol
names, in combination with parenthesis and + - * / & % ^ | operators.
In case there are multiple matches (i.e. a symbol that has the same name as a
register), you may add a prefix character as a hint: '#' for registers, '@'
for symbols, and '$' for numeric values. Use 0x for hexadecimal values.

下面将介绍几个常用的功能。

Breakpoint,Step & Unassemble,Dump,Trace

GXemul 提供了断点、单步执行(指令级别)的调试功能;除此之外,GXemul 还提供了反汇编、内存导出等功能。

ADD BREAKPOINT

如下,启动模拟器后,在内部控制台中输入 breakpoint add page_insert,即可为 page_insert 函数增加断点。随后使用 c(continue)命令让模拟器继续运行,模拟器将运行至下一个断点处。

page_insert 为例:

1
2
3
4
5
6
7
8
9
GXemul> breakpoint add page_insert
0: 0x80014e38 (page_insert)
GXemul> c
init.c: mips_init() is called
Memory size: 65536 KiB, number of pages: 16384
to memory 80430000 for struct Pages.
pmap.c: mips vm init success
BREAKPOINT: pc = 0x80014e38
(The instruction has not yet executed.)
STEP

如下,使用 step 即可让模拟器执行 1 条汇编指令(基本指令)。

1
GXemul> step

进一步地,使用 step 100 即可让模拟器执行 100 条汇编指令(基本指令)。

1
GXemul> step 100

仍以上面的 page_insert 为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
GXemul> breakpoint add page_insert
0: 0x80014e38 (page_insert)
GXemul> c
init.c: mips_init() is called
Memory size: 65536 KiB, number of pages: 16384
to memory 80430000 for struct Pages.
pmap.c: mips vm init success
BREAKPOINT: pc = 0x80014e38
(The instruction has not yet executed.)
GXemul> step 20
<page_insert>
80014e38: 27bdffe0 addiu sp,sp,-32
80014e3c: afbf001c sw ra,28(sp) [0x803fff7c]
80014e40: afbe0018 sw fp,24(sp) [0x803fff78]
80014e44: 03a0f025 or fp,sp,zr
80014e48: afc40020 sw a0,32(fp) [0x803fff80]
80014e4c: afc50024 sw a1,36(fp) [0x803fff84]
80014e50: afc60028 sw a2,40(fp) [0x803fff88]
80014e54: afc7002c sw a3,44(fp) [0x803fff8c]
80014e58: 27c20014 addiu v0,fp,20
80014e5c: 00403825 or a3,v0,zr
80014e60: 00003025 or a2,zr,zr
80014e64: 8fc5002c lw a1,44(fp) [0x803fff8c]
80014e68: 8fc40020 lw a0,32(fp) [0x803fff80]
80014e6c: 0c005311 jal 0x80014c44 <pgdir_walk>
80014e70: 00000000 (d) nop
<pgdir_walk>
80014c44: 27bdffc8 addiu sp,sp,-56
80014c48: afbf0034 sw ra,52(sp) [0x803fff5c]
80014c4c: afbe0030 sw fp,48(sp) [0x803fff58]
80014c50: afb0002c sw s0,44(sp) [0x803fff54]
80014c54: 03a0f025 or fp,sp,zr
80014c58: afc40038 sw a0,56(fp) [0x803fff60]
UNASSEMBLE

如下,使用 unassemble 命令,导出某一个地址后续(或附近)的汇编指令序列。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
GXemul> unassemble
80014c5c: afc5003c <- sw a1,60(fp)
80014c60: afc60040 sw a2,64(fp)
80014c64: afc70044 sw a3,68(fp)
80014c68: 8fc2003c lw v0,60(fp)
80014c6c: 00000000 nop
80014c70: 00021582 srl v0,v0,22
80014c74: 00021080 sll v0,v0,2
80014c78: 8fc30038 lw v1,56(fp)
80014c7c: 00000000 nop
80014c80: 00621021 addu v0,v1,v0
80014c84: afc20018 sw v0,24(fp)
80014c88: 8fc20018 lw v0,24(fp)
80014c8c: 00000000 nop
80014c90: 8c420000 lw v0,0(v0)
80014c94: 00000000 nop
80014c98: 30420200 andi v0,v0,0x0200
80014c9c: 14400031 bne zr,v0,0x80014d64 <pgdir_walk+0x120>
80014ca0: 00000000 nop
80014ca4: 8fc20040 lw v0,64(fp)
80014ca8: 00000000 nop
DUMP DATA

如下,使用 dump 命令,导出某一个地址后续(或附近)的内存信息。下面以查看 curenv 的值以及其指向的进程控制块为例:

1
2
3
4
5
6
7
GXemul> dump curenv
0x800167a0 804320e8 00000003 00000000 .C .........
0x800167b0 00000002 804321d0 00000000 00000000 .....C!.........
0x800167c0 80432000 00000001 00000000 00000000 .C .............
0x800167d0 00000000 00000000 00000000 00000000 ................
0x800167e0 00000000 00000000 00000000 00000000 ................
..........

根据 curenv 的定义,其类型为 struct Env *,因此 0x800167a4 中存储的是一个地址(指向一个 struct Env)。根据上述 dump 结果,可以知道这个全局指针指向了 0x804320e8 这一地址。再通过 dump 0x804320e8 即可找到当前 curenv 指向的 struct Env

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
GXemul> dump 0x804320e8
0x804320e0 00000000 00000000 ........
0x804320f0 00000001 00000025 00400920 0040d2c4 .......%.@. .@..
0x80432100 0040d2c4 7f3fdfcc 00000000 00000000 .@...?..........
0x80432110 00000000 00000000 00000000 00000000 ................
0x80432120 00000000 00000000 0040d2cc 00000007 .........@......
0x80432130 00000000 7f3fdfcc 00000000 00400920 .....?.......@.
0x80432140 00000000 00000000 00000000 00000000 ................
0x80432150 7f3fdb80 82000000 00000000 7f3fdb80 .?...........?..
0x80432160 00000000 004009d0 10081004 00000000 .....@..........
0x80432170 00000000 00408000 00001000 00400aa0 .....@.......@..
0x80432180 00400aa0 804321d0 800167b4 00000c01 .@...C!...g.....
0x80432190 00000000 00000001 83ff3000 03ff3000 ..........0...0.
0x804321a0 00000000 80019270 00000001 00000000 .......p........
0x804321b0 00000000 00000000 00000000 00000000 ................
0x804321c0 00000000 00000000 00000002 00000000 ................
0x804321d0 00000000 00000000 00000000 00000000 ................
0x804321e0 00000000 00000000 ........

即可查看当前正运行的进程控制块的信息。类似地,可以查看任何全局变量的值,以及大部分内核数据结构的信息。

DUMP REGISTERS

通过 reg 命令导出通用寄存器的值:

1
2
3
4
5
6
7
8
9
10
11
GXemul> reg
cpu0: pc = 80012620
cpu0: hi = 00000000 lo = 00000000
cpu0: at = 00000000 v0 = 00000000 v1 = 82000000
cpu0: a0 = 803fffb8 a1 = 82000000 a2 = 82000000 a3 = 00000000
cpu0: t0 = 7f3fdf48 t1 = 80012a60 t2 = 80012b20 t3 = 00000000
cpu0: t4 = 00000000 t5 = 00000000 t6 = 00000000 t7 = 00000000
cpu0: s0 = 7f4002b8 s1 = 00001c03 s2 = 00410000 s3 = 00000003
cpu0: s4 = 00000000 s5 = 00000000 s6 = 00000000 s7 = 00000000
cpu0: t8 = 00000000 t9 = 00000000 k0 = 7f3fdf48 k1 = 803fffb8
cpu0: gp = 00000000 sp = 803ffeec fp = 00000000 ra = 80012b50

通过 reg, 0 命令导出协处理器 0(CP0)中寄存器的值:

1
2
3
4
5
GXemul> reg, 0
cpu0: index=00000f00 random=00003700 entrylo0=03fbb600 entrylo1=00000000
cpu0: context=00001008 pagemask=00001fff wired=00000000 reserv7=00000000
cpu0: badvaddr=00402b2c count=00000000 entryhi=00402080 compare=00000000
cpu0: status=10081004 cause=00001020 epc=004000c0 prid=00000220

通过 tlbdump 命令导出 TLB 中的信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
GXemul> tlbdump
cpu0: (index=0xf random=0x37)
0: (invalid)
1: (invalid)
2: (invalid)
3: (invalid)
4: (invalid)
5: (invalid)
6: (invalid)
7: (invalid)
8: vaddr=0x00404000 (asid 01), paddr=0x03feb000 D
9: vaddr=0x7f82f000 (asid 01), paddr=0x00430000 D
10: vaddr=0x7fd80000 (asid 01), paddr=0x03fd9000 D
11: vaddr=0x7fdff000 (asid 01), paddr=0x03ff3000 D
12: vaddr=0x00408000 (asid 01), paddr=0x03fe7000 D
13: vaddr=0x00402000 (asid 01), paddr=0x03fed000 D
14: vaddr=0x00409000 (asid 01), paddr=0x03fe6000 D
15: (invalid)
16: vaddr=0x7f400000 (asid 01), paddr=0x00432000 D
17: vaddr=0x0040d000 (asid 01), paddr=0x03fe2000 D
18: vaddr=0x7f3fd000 (asid 01), paddr=0x03ff2000 D
19: vaddr=0x00401000 (asid 01), paddr=0x03fee000 D
20: vaddr=0x00400000 (asid 01), paddr=0x03ff0000 D
21: vaddr=0x7f400000 (asid 03), paddr=0x00432000 D
22: vaddr=0x00403000 (asid 04), paddr=0x03fa0000
23: vaddr=0x00403000 (asid 05), paddr=0x03b69000 D
24: vaddr=0x10041000 (asid 01), paddr=0x03b79000 D
25: (invalid)
26: vaddr=0x10040000 (asid 01), paddr=0x03b7a000 D
27: (invalid)
28: vaddr=0x7f400000 (asid 02), paddr=0x00432000 D
29: vaddr=0x1003f000 (asid 01), paddr=0x03b7b000 D
30: (invalid)
31: vaddr=0x00403000 (asid 03), paddr=0x03fa0000
32: vaddr=0x7f3fd000 (asid 03), paddr=0x03b88000 D
33: vaddr=0x61000000 (asid 05), paddr=0x03fd8000 D
34: vaddr=0x5fc04000 (asid 05), paddr=0x03b5f000 D
35: vaddr=0x7fd7f000 (asid 05), paddr=0x03b62000 D
36: vaddr=0x00408000 (asid 05), paddr=0x03b64000 D
37: vaddr=0x1003e000 (asid 01), paddr=0x03b7c000 D
38: (invalid)
39: vaddr=0x00402000 (asid 03), paddr=0x03fa1000
40: vaddr=0x00400000 (asid 03), paddr=0x03fa4000
41: vaddr=0x00409000 (asid 04), paddr=0x03f9a000
42: vaddr=0x00407000 (asid 04), paddr=0x03b82000 D
43: vaddr=0x7f400000 (asid 04), paddr=0x00432000 D
44: vaddr=0x0080d000 (asid 04), paddr=0x03fa7000 D
45: vaddr=0x7f3fd000 (asid 04), paddr=0x03b86000 D
46: vaddr=0x00402000 (asid 04), paddr=0x03fa1000
47: vaddr=0x00400000 (asid 04), paddr=0x03fa4000
48: vaddr=0x1003d000 (asid 01), paddr=0x03b7d000 D
49: (invalid)
50: vaddr=0x5fc01000 (asid 05), paddr=0x03fff000 D
51: vaddr=0x00400000 (asid 05), paddr=0x03b6d000 D
52: vaddr=0x00402000 (asid 05), paddr=0x03b6a000 D
53: vaddr=0x00409000 (asid 05), paddr=0x03b63000 D
54: vaddr=0x7f3fd000 (asid 05), paddr=0x03b70000 D
55: vaddr=0x00402000 (asid 02), paddr=0x03fbb000 D
56: vaddr=0x7f3fd000 (asid 02), paddr=0x03fc1000 D
57: vaddr=0x00401000 (asid 02), paddr=0x03fbc000 D
58: vaddr=0x00400000 (asid 02), paddr=0x03fbe000 D
59: vaddr=0x10042000 (asid 01), paddr=0x03b78000 D
60: vaddr=0x7fc40000 (asid 01), paddr=0x03fde000 D
61: vaddr=0x10002000 (asid 01), paddr=0x03fdc000 D
62: vaddr=0x10001000 (asid 01), paddr=0x03fdf000 D
63: vaddr=0x10003000 (asid 01), paddr=0x03fd8000 D
TRACE

使用 trace 可以帮助同学们了解程序的运行轨迹。

1
2
3
4
5
6
7
8
GXemul> trace
show_trace_tree = ON (was: OFF)
GXemul> c
<env_run(0x80432488,0x804321d0,0,&env_sched_list,..)>
<bcopy(0x81ffff64,0x804321d0,156)>
<lcontext(0x83b81000,0x8043226c,0x8043226c,&env_sched_list,..)>
<env_pop_tf(0x80432488,0x140,0x8043226c,&env_sched_list,..)>
........

Reference

  • Title: GXemul-note
  • Author: Charles
  • Created at : 2023-05-01 12:20:50
  • Updated at : 2023-11-05 21:36:19
  • Link: https://charles2530.github.io/2023/05/01/gxemul-note/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments