В отладчике Bochs'a есть замечательная возможность, можно загрузить отладочные символы из .map файла. Причем, данный формат крайне простой - это просто набор строк вида
Code: Select all
16ичныйадрес имя
Code: Select all
0000000080023628 create_usb_thread
Но как нам сформировать этот самый .map файл? Ведь в ядре тысячи переменных и функций, не будем же мы руками вбивать их и их адреса в файл?
Поэтому за нас это сделает софт.
Сперва, мы должны скомпилировать ядро Колибри с отладочными символами, да, fasm умеет их генерировать, у него свой формат .fas. Для этого возьмем build.bat и изменим строку
Code: Select all
fasm -m 65536 kernel.asm kernel.mnt
Code: Select all
fasm -m 65536 kernel.asm -s kernel.fas kernel.mnt
Сам формат .fas досточно сложный, нам же потребуется лишь малая часть информации из него. Воспользуемся утилитой symbols, она поставляется вместе с самим fasm'ом (чтобы скомпилировать ее, зайдите в tools/win32 и выполните fasm symbols.asm symbols.exe). Данная утилита читает из .fas файла имена и адреса символов, а также место их объявления в исходнике. Теперь выполним
Code: Select all
symbols kernel.fas kernel.txt
Code: Select all
tcp_output.options_done: 0x00000000800336B6, defined in network/tcp_output.inc[404]
Наконец, для конвертации в .map мы пишем скрипт на питоне fastxt2bochs_map.py следующего содержания:
Code: Select all
import re
import sys
if len(sys.argv) < 2 or sys.argv[1].strip() == '':
print('error: no input file\nusage: {:s} <file>'.format(sys.argv[0]))
exit(-1)
inp_path = sys.argv[1].strip()
out_path = inp_path + '.map'
inp = open(inp_path,'r')
inp_text = inp.read()
inp.close()
regex1 = re.compile(r"[\S]+\:\s0x[\da-fA-F]*")
res = re.findall(regex1, inp_text)
#print(res)
out = open(out_path, 'w')
for ln in res:
splt = ln.split()
sym_addr = int(splt[1],16)
sym_name = splt[0][:-1]
out.write('{:016x} {:s}\n'.format(sym_addr, sym_name))
out.close()
Code: Select all
fastxt2bochs_map.py kernel.txt
Теперь расскажу как с ними, собственно, работать. Сначала приготовьте образ Колибри, скачайте самый свежий kolibri.img (это важно т.к если ваш образ колибри более старый (прошлогодний например), чем исходники ядра из которых вы получили символы на предыдущем шаге, то могут быть проблемы). Далее настраиваем конфигурацию машины (я просто прикреплю свой bochsrc.bxrc в конце).
Запускаем нашу машину в Bochs дебаггере (bochsdbg) . Видим такое приглашение ко вводу <bochs:1>
Далее выполняем следующие команды.
Загружаем наши отладочные символы:
Code: Select all
ldsym "kernel.txt.map"
Code: Select all
lb "high_code"
Code: Select all
cont
Дойдя до брейкпоинта, bochs останавливает выполнение кода и снова дает возможность вводить нам команды.
Выведем, например, значения всех регистров, набрав команду:
Code: Select all
r
Code: Select all
u "high_code" "high_code"+50
Code: Select all
x /1wx "CURRENT_TASK"
P.S мой файл bochsrc.bxrc (пути только на свои подправьте ) :
Spoiler:
# configuration file generated by Bochsplugin_ctrl: unmapped=true, biosdev=true, speaker=true, extfpuirq=true, parallel=true, serial=true, gameport=true
config_interface: win32config
display_library: win32
memory: host=128, guest=128
romimage: file="D:\ProgramFiles\Bochs-2.6.11/BIOS-bochs-latest", address=0x00000000, options=none
vgaromimage: file="D:\ProgramFiles\Bochs-2.6.11/VGABIOS-lgpl-latest"
boot: floppy
floppy_bootsig_check: disabled=0
floppya: type=1_44, 1_44="D:\Documents\ПРОГРАММНЫЕ ПРОЕКТЫ И ЗАДАЧИ\KolibriOS_projects\Kolibri_kernel\trunk\kolibri.img", status=inserted, write_protected=0
# no floppyb
ata0: enabled=true, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
ata0-master: type=none
ata0-slave: type=none
ata1: enabled=true, ioaddr1=0x170, ioaddr2=0x370, irq=15
ata1-master: type=none
ata1-slave: type=none
ata2: enabled=false
ata3: enabled=false
optromimage1: file=none
optromimage2: file=none
optromimage3: file=none
optromimage4: file=none
optramimage1: file=none
optramimage2: file=none
optramimage3: file=none
optramimage4: file=none
pci: enabled=1, chipset=i440fx
vga: extension=vbe, update_freq=60, realtime=1
cpu: count=1, ips=8000000, model=bx_generic, reset_on_triple_fault=1, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0
cpuid: level=6, stepping=3, model=3, family=6, vendor_string="GenuineIntel", brand_string=" Intel(R) Pentium(R) 4 CPU "
cpuid: mmx=true, apic=xapic, simd=sse2, sse4a=false, misaligned_sse=false, sep=true
cpuid: movbe=false, adx=false, aes=false, sha=false, xsave=false, xsaveopt=false, x86_64=true
cpuid: 1g_pages=false, pcid=false, fsgsbase=false, smep=false, smap=false, mwait=true
cpuid: vmx=1
print_timestamps: enabled=0
port_e9_hack: enabled=0
private_colormap: enabled=0
clock: sync=none, time0=local, rtc_sync=1
# no cmosimage
log: -
logprefix: %t%e%d
debug: action=ignore
info: action=report
error: action=report
panic: action=ask
keyboard: type=mf, serial_delay=200, paste_delay=100000, user_shortcut=none
mouse: type=ps2, enabled=false, toggle=ctrl+f10
sound: waveoutdrv=win, waveout=none, waveindrv=win, wavein=none, midioutdrv=win, midiout=none
speaker: enabled=true, mode=sound
parport1: enabled=true, file=none
parport2: enabled=false
com1: enabled=true, mode=null
com2: enabled=false
com3: enabled=false
com4: enabled=false