Skip to content

Instantly share code, notes, and snippets.

@Ragmaanir
Last active June 14, 2018 11:49
Show Gist options
  • Save Ragmaanir/0f61220276c794abea840976457e1aee to your computer and use it in GitHub Desktop.
Save Ragmaanir/0f61220276c794abea840976457e1aee to your computer and use it in GitHub Desktop.
osdev-gdb
global helvede_kernel_long_mode
global gdb_synchronization_breakpoint
section .text
bits 64
helvede_kernel_long_mode:
cli
call call_helvede_kernel_main
jmp permanent_halt
call_helvede_kernel_main:
call wait_for_gdb
; initialize stack
extern helvede_kernel_stack_top
mov rsp, helvede_kernel_stack_top
extern helvede_kernel_heap_start
; NOTE: rdi is used on Linux, rcx on Windows
mov rdi, helvede_kernel_heap_start
push rbp
extern helvede_kernel_main
call helvede_kernel_main
pop rbp
ret
; wait until condition is changed via GDB to prevent bug "g packet reply is too long"
; see: https://stackoverflow.com/questions/8662468/remote-g-packet-reply-is-too-long
wait_for_gdb:
mov rax, 0
.loop_start:
; mov rbx, [text_waiting_for_gdb]
; mov qword [0xb8000 + 0x100], rbx
call gdb_synchronization_breakpoint
test rax, rax
jz .loop_start
; mov qword [0xb8000 + 0x100], text_done_waiting
ret
; This breakpoint is called from the wait_for_gdb-loop. Once GDB is connected
; to QEMU the breakpoint is triggered. The wait_for_gdb-loop can then be skipped
; by executing "set $rax = 1" in GDB and continuing.
gdb_synchronization_breakpoint:
; mov rbx, [text_gdb_breakpoint_reached]
; mov qword [0xb8000 + 0x108], rbx
ret
; snip ...
rm -r output
mkdir -p output/objects
mkdir -p output/image/boot/grub
echo "--- g++ ---" &&
g++ -std=c++1y -masm=intel -c source/kernel.cpp -o output/objects/kernel.o -ggdb -ffreestanding -O2 -Wall -Wextra -fno-exceptions -fno-rtti -fno-stack-protector -fno-builtin -msse3 -mstackrealign -Wno-unused-parameter -mno-red-zone
#clang-3.6 -std=c++14 -m64 -masm=intel -c source/kernel.cpp -o output/objects/kernel.o -ffreestanding -O2 -Wall -Wextra -fno-exceptions -fno-rtti -fno-stack-protector -fno-use-cxa-atexit -Wno-gnu-array-member-paren-init -Wno-unused-parameter
echo "--- NASM ---" &&
nasm -f elf64 -g -F dwarf source/boot_header.asm -o output/objects/boot_header.o &&
nasm -f elf64 -g -F dwarf source/boot_long_mode.asm -o output/objects/boot_long_mode.o &&
nasm -f elf64 -g -F dwarf source/boot.asm -o output/objects/boot.o &&
nasm -f elf64 -g -F dwarf source/interrupts.asm -o output/objects/interrupts.o &&
echo "--- Linking ---" &&
ld -m elf_x86_64 -n -nostdlib -o output/image/boot/kernel.bin -T source/linker.ld output/objects/boot_header.o output/objects/boot.o output/objects/boot_long_mode.o output/objects/interrupts.o output/objects/kernel.o &&
cp source/grub.cfg output/image/boot/grub/ &&
grub-mkrescue -o output/image.iso output/image
#!/bin/bash
#./build_docker.sh
./build.sh
qemu-system-x86_64 -hda output/image.iso -s -serial file:stdio -D qemu.log -d int,cpu_reset -no-reboot -no-shutdown &
# required so that gdb connects *after*
# kernel changed to long-mode and is stuck in
# wait_for_gdb-loop in order to prevent
# "g packet reply is too long" which according to
# https://stackoverflow.com/questions/8662468/remote-g-packet-reply-is-too-long
# is caused by a change in the instruction set
# triggered by changing to long-mode.
sleep 1
# -ex "symbol-file output/objects/kernel.o" \
# -ex "break helvede_kernel_main"
# -ex "set arch i386:x86-64" \
# gdb \
# -ex "symbol-file output/image/boot/kernel.bin" \
# -ex "set arch i386:x86-64" \
# -ex "break gdb_synchronization_breakpoint\\ncommands\\nset $rax = 1\\ncontinue\\nend" \
# -ex "target remote localhost:1234"
gdb -x gdb_commands
symbol-file output/image/boot/kernel.bin
set arch i386:x86-64
set pagination off
print "REGISTER BREAKPOINT"
break gdb_synchronization_breakpoint
commands
print "BREAKPOINT..."
set $rax = 1
continue
end
print "CONNECTING..."
target remote localhost:1234
rm: cannot remove 'output': Device or resource busy
--- g++ ---
In file included from source/kernel.cpp:21:
source/interrupt_descriptor_table.hpp: In member function 'void Helvede::InterruptDescriptorTable::install()':
source/interrupt_descriptor_table.hpp:211:19: warning: variable 't' set but not used [-Wunused-but-set-variable]
VGATerminal t = _t;
^
In file included from source/kernel.cpp:22:
source/tests.hpp: In instantiation of 'void Helvede::Tests::assert_equal(A, B, RawString) [with A = unsigned int; B = int; RawString = const char*]':
source/tests.hpp:32:7: required from here
source/tests.hpp:10:15: warning: comparison of integer expressions of different signedness: 'unsigned int' and 'int' [-Wsign-compare]
if(left == right) {
~~~~~^~~~~~~~
--- NASM ---
--- Linking ---
xorriso 1.4.8 : RockRidge filesystem manipulator, libburnia project.
Drive current: -outdev 'stdio:output/image.iso'
Media current: stdio file, overwriteable
Media status : is blank
Media summary: 0 sessions, 0 data blocks, 0 data, 35.6g free
Added to ISO image: directory '/'='/tmp/grub.2bFgwL'
xorriso : UPDATE : 898 files added in 1 seconds
Added to ISO image: directory '/'='/root/helvede/output/image'
xorriso : UPDATE : 902 files added in 1 seconds
xorriso : NOTE : Copying to System Area: 512 bytes from file '/usr/lib/grub/i386-pc/boot_hybrid.img'
ISO image produced: 10078 sectors
Written to medium : 10078 sectors at LBA 0
Writing to 'stdio:output/image.iso' completed successfully.
WARNING: Image format was not specified for 'output/image.iso' and probing guessed raw.
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
Specify the 'raw' format explicitly to remove the restrictions.
warning: TCG doesn't support requested feature: CPUID.01H:ECX.vmx [bit 5]
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
The target architecture is assumed to be i386:x86-64
$1 = "REGISTER BREAKPOINT"
Breakpoint 1 at 0x1008c9: file source/boot_long_mode.asm, line 51.
$2 = "CONNECTING..."
helvede_kernel_long_mode () at source/boot_long_mode.asm:38
38 test rax, rax
(gdb) c
Continuing.
Breakpoint 1, gdb_synchronization_breakpoint () at source/boot_long_mode.asm:51
51 ret
$3 = "BREAKPOINT..."
Program received signal SIGQUIT, Quit.
0x53525150fadb8aa6 in ?? ()
(gdb)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment