gdb: get symbols working!!!

This commit is contained in:
Ciro Santilli
2019-08-24 00:00:02 +00:00
parent 52a22c4b18
commit 04b50572b2
6 changed files with 51 additions and 54 deletions

View File

@@ -2,6 +2,7 @@
COMMON ?= common.h
DOC_OUT = README.html
ELF_EXT = .elf
LD ?= ld
LINKER_SCRIPT ?= linker.ld
# Use gcc so that the preprocessor will run first.
@@ -10,7 +11,7 @@ GAS_EXT ?= .S
NASM_EXT ?= .asm
OBJ_EXT ?= .o
OUT_EXT ?= .img
QEMU ?= qemu-system-i386
QEMU ?= qemu-system-i386 -drive 'file=$(RUN_FILE),format=raw' -smp 2
RUN ?= bios_hello_world
RUN_ARGS ?= -soundhw pcspk
RUN_SERIAL ?= bios_hello_world_serial
@@ -25,12 +26,11 @@ RUN_FILE_SERIAL := $(RUN_SERIAL)$(OUT_EXT)
all: $(OUTS)
%$(OUT_EXT): %$(OBJ_EXT) $(LINKER_SCRIPT)
@# Failed attempt at getting debug symbols.
@#$(LD) -melf_i386 -o '$(@:$(OUT_EXT)=.elf)' -T '$(LINKER_SCRIPT)' '$<'
$(LD) --oformat binary -o '$@' -T '$(LINKER_SCRIPT)' '$<'
$(LD) -melf_i386 -nostdlib -o '$(@:$(OUT_EXT)=$(ELF_EXT))' -T '$(LINKER_SCRIPT)' '$<'
objcopy -O binary '$(@:$(OUT_EXT)=.elf)' '$@'
%$(OBJ_EXT): %$(GAS_EXT) $(COMMON)
$(GAS) -c -g -o '$@' '$<'
$(GAS) -m32 -c -ggdb3 -o '$@' '$<'
%$(OUT_EXT): %$(NASM_EXT)
nasm -f bin -o '$@' '$<'
@@ -39,14 +39,14 @@ all: $(OUTS)
$(COMMON):
clean:
rm -fr '$(DOC_OUT)' *$(OBJ_EXT) *$(OUT_EXT) *$(TMP_EXT)
rm -fr '$(DOC_OUT)' *$(ELF_EXT) *$(OBJ_EXT) *$(OUT_EXT) *$(TMP_EXT)
run: $(RUN_FILE)
$(QEMU) -drive 'file=$(RUN_FILE),format=raw' -smp 2 $(RUN_ARGS)
$(QEMU) $(RUN_ARGS)
debug: $(RUN_FILE)
$(QEMU) -hda '$(RUN_FILE)' -S -s &
gdb -x gdb.gdb
$(QEMU) -S -s &
gdb -quiet -x gdb.gdb '$(<:$(OUT_EXT)=$(ELF_EXT))'
bochs: $(RUN_FILE)
# Supposes size is already multiples of 512.

View File

@@ -180,15 +180,21 @@ It should also be possible to run a GUI inside the container, but I haven't test
=== GDB step debug
TODO get it working nicely:
To GDB step debug the program, run it with:
....
./run bios_hello_world debug
....
This will only cover specifics, you have to know GDB debugging already.
This will leave you at the very first instruction executed by QEMU, which is the beginning of our `BEGIN` macro.
How to have debug symbols: https://stackoverflow.com/questions/32955887/how-to-disassemble-16-bit-x86-boot-sector-code-in-gdb-with-x-i-pc-it-gets-tr/32960272#32960272 TODO implement here. Needs to point GDB to an ELF file in addition to the remote listen.
You can then basically debug as you would a normal userland program, notably:
* I then highly recommend that you use https://github.com/cyrus-and/gdb-dashboard[GDB Dashboard] to see what is going on.
* `n` skips over macros
* `ni` steps within macros. But you will need to enable the printing of assembly code on GDB Dashboard to see where you are at
Debug symbols are obtained by first linking ELF files, and then using `objcopy` on them to generate the final image. We then pass the ELF files with the debug information to GDB: https://stackoverflow.com/questions/32955887/how-to-disassemble-16-bit-x86-boot-sector-code-in-gdb-with-x-i-pc-it-gets-tr/32960272#32960272
How to step over `int` calls: http://stackoverflow.com/questions/24491516/how-to-step-over-interrupt-calls-when-debugging-a-bootloader-bios-with-gdb-and-q
@@ -2104,6 +2110,38 @@ But I have since change my mind, and if I ever touch this again seriously, I wou
If this is done, we this repo should then be merged into: https://github.com/cirosantilli/linux-kernel-module-cheat/tree/87e846fc1f9c57840e143513ebd69c638bd37aa8#baremetal-setup together with the ARM Newlib baremetal setups present there.
=== Serial UART
What the heck is a serial in the real world: https://unix.stackexchange.com/questions/307390/what-is-the-difference-between-ttys0-ttyusb0-and-ttyama0-in-linux/367882#367882
Currently all text output is done the display, and that was a newbie design choice from before I knew the serial existed. The serial is just generally more minimal and elegant than the display, and should have been used instead.
TODO: get working on QEMU, working on Bochs:
....
./run bios_hello_world_serial bochs
cat bios_hello_world_serial.tmp.serial
....
The file content:
....
hello world
....
Source: link:bios_hello_world_serial.S[]
Bibliography:
* https://stackoverflow.com/questions/22571379/intel-galileo-bare-metal-uart
* https://stackoverflow.com/questions/27594297/how-to-print-a-string-to-the-terminal-in-x86-64-assembly-nasm-without-syscall
This would open up:
* gem5 benchmarking and exploration, currently blocked on https://stackoverflow.com/questions/50364863/how-to-get-graphical-gui-output-and-user-touch-keyboard-mouse-input-in-a-ful/50364864#50364864
* automated unit tests. Ha, like I'm gonna be that diligent!
* easily working on ARM in a more uniform way
=== Macros vs functions
Using macros for now on link:common.h[] instead of functions because it simplifies the linker script.
@@ -2165,35 +2203,6 @@ Knowing the following will help a lot:
While it is possible to learn those topics as you go along, and it is almost certain that you will end up learning more about them, we will not explain them here in detail.
== TODO
=== Serial UART
TODO: get working on QEMU, working on Bochs:
....
./run bios_hello_world_serial bochs
cat bios_hello_world_serial.tmp.serial
....
File content:
....
hello world
....
Source: link:bios_hello_world_serial.S[]
Bibliography:
* https://stackoverflow.com/questions/22571379/intel-galileo-bare-metal-uart
* https://stackoverflow.com/questions/27594297/how-to-print-a-string-to-the-terminal-in-x86-64-assembly-nasm-without-syscall
This would open up:
* gem5 benchmarking and exploration, currently blocked on https://stackoverflow.com/questions/50364863/how-to-get-graphical-gui-output-and-user-touch-keyboard-mouse-input-in-a-ful/50364864#50364864
* automated unit tests. Ha, like I'm gonna be that dilligent!
== Bibliography
=== Intel manual

View File

@@ -2,7 +2,6 @@
#include "common.h"
BEGIN
DBG
mov $msg, %si
mov $0x0e, %ah
loop:

View File

@@ -7,10 +7,6 @@
/* Helpers */
.macro DBG
mov %ax, 0x9000
.endm
/* Push registers ax, bx, cx and dx. Lightweight `pusha`. */
.macro PUSH_ADX
push %ax

View File

@@ -14,13 +14,7 @@ end
break *0x7c00
continue
# Magic address. Add a:
#
# mov %ax, 0x9000
#
# to your program to break there. Shortcut macro on common.h:
#
# DBG
# https://cirosantilli.com/x86-bare-metal-examples#gdb-step-debug
awatch *0x9000
commands
silent

View File

@@ -3,7 +3,6 @@
#include "common.h"
BEGIN
CLEAR
DBG
/* Set address of the handler for interrupt 0. */
movw $handler, 0x00
/* Set code segment of the handler for interrupt 0. */