next sector of NASM bootloader is not loading when using LD - nasm

I am trying to create a bootloader that allows rust code to be bootable, but i am very new to OS dev, makefile, and assembly, and I'm still an amateur in Rust. I'm trying to use int 13h (ah 0h2) to read the next sector and execute that assembly code which will then, at some point, be executing rust code. however, the code in my "stage one" of my bootloader that is past the boot sector never seems to run. here is my code:
boot.asm
;[ORG 0x7c00]
[BITS 16]
global _start
_start:
; set segment registers
; (user3840170 said to set up the segment registers, but this didn't fix the problem)
cli
xor ax, ax ; code segment
mov ds, ax ; data segment
mov es, ax ; extra segment
mov ss, ax ; stack segment
mov bp, 7c00h ; base pointer
mov sp, 7c00h ; stack pointer
sti
; print message
mov si, msg1
call print
; read the next sectors, then jump
mov al, 01h ; sectors to read (1)
mov bx, 7e00h ; buffer address (512 bytes away from current address 0x7c00)
mov cx, 0002h ; cylinder and sector numbers (cylinder 0, sector 2)
mov dl, 0 ; drive 0 (boot drive)
mov dh, 0 ; head 0
mov ah, 02h
int 13h
jmp 7e00h ; jumps to stage one
%include 'Bootloader/print.asm'
msg1: db "bootsector is loading stage 1", 0
times 510-($ - $$) db 0
dw 0xAA55
;;;;;;;;;;;
; STAGE ONE
;;;;;;;;;;;
mov si, msg2
call print
msg2: db 'Hello', 0
mov al, 'A'
mov ah, 0eh
int 10h
times 1024 - ($ - $$) db 0
print.asm
;set of things for printing strings to TTY
print:
mov bx, 0
.loop:
lodsb
cmp al, 0
je .done
call print_char
jmp .loop
.done:
ret
print_char:
mov ah, 0eh
int 10h
ret
print_line:
mov al, 0ah
call print_char
mov al, 0dh
call print_char
ret
and lastly, the Makefile that I am using to build this to .iso and run it in VirtualBox: (I am running the genasm command, I haven't written the Rust kernel yet)
genfull: clean
mkdir -p iso
powershell.exe -Command "cd Kernel; cargo rustc -Z build-std=core -- --emit obj=kernelNP.o; cd .."
objcopy ./Kernel/kernelNP.o Kernel.o --prefix-alloc-sections='.rust' && rm -rf ./Kernel/kernelNP.o
nasm -f elf64 ./Bootloader/boot.asm -o bootsec.o
ld Kernel.o bootsec.o --oformat binary -o main.img
genisoimage -quiet -no-emul-boot -V 'BOOT' -input-charset iso8859-1 -o ./out/boot.iso -b main.img -hide main.img iso/
rm -rf ./*.img ./*.bin ./iso/ ./*.o
genasm: clean
mkdir -p iso
nasm -f elf64 ./Bootloader/boot.asm -o bootsec.o
ld bootsec.o --oformat binary -Ttext 0x7c00 -o iso/main.img
genisoimage -quiet -no-emul-boot -V 'BOOT' -input-charset iso8859-1 -o ./out/boot.iso -b main.img -hide main.img iso/
rm -rf ./*.img ./*.bin ./iso/ ./*.o
clean:
rm -rf ./*.img ./*.bin ./iso/ ./*.o
please help me with why the second sector never runs!

I figured out the problem, it was the makefile. here is the new genasm:
genasm: clean
mkdir -p iso
nasm -g -f elf32 -F dwarf -o boot.o ./Bootloader/boot.asm
ld -melf_i386 -Ttext=0x7c00 -nostdlib --nmagic -o boot.elf boot.o
objcopy -O binary boot.elf iso/main.img
genisoimage -quiet -no-emul-boot -V 'BOOT' -input-charset iso8859-1 -o ./out/boot.iso -b main.img -hide main.img iso/
rm -rf ./*.img ./*.bin ./iso/ ./*.o ./*.elf

Related

Cannot print the string to which the stack address points using INT80 in Ubuntu system

I can print character in label that in section .data
But I can't print character use stack address
section .data
break db "a"
section .text
global _start
_start:
mov rax, qword 'a'
push rax
; push 'a' to stack
mov rax,4
mov rbx,1
; get stack top pointer and mov to rcx register
mov rcx,rsp
; If replace rsp with label <break> that can print newlines character
; mov rcx,break
mov rdx,1
int 80h
pop rax
call quit
quit:
mov rbx, 0
mov rax, 1
int 80h
ret
console>
not print anything
If replace rsp with label that can print newlines
; mov rcx, rsp
mov rcx, break
console>a#
print one character
Makefile
.PHONY: test
test:
nasm -f elf64 test.asm
ld -s -o test test.o
./test
.PHONY: test_debug
test_debug:
nasm -f elf64 -F dwarf -g test.asm
ld -g -o test test.o
gdb test

Gdb problem when debugging with breakpoints and symbols

I coding assembly with Nasm, i want debug the program using gdb, but it not works when i put a breakpoint and run the program.
The program compile fine and link too, the problem is gdb.
Here is the commands to compile:
nasm -f elf64 -F dwarf -g types.asm
nasm -f elf64 -F dwarf -g functions.asm
nasm -f elf64 -F dwarf -g Hello.asm
ld -g -o Hello Hello.o functions.o types.o
This is the file i want debug Hello.asm:
%include "functions.asm"
section .bss
res: resb 1
fout: resb 1
section .text
global _start: ;must be declared for linker (ld)
section .data
msg db 'Hello, world!', 0xa ;string to be printed
len equ $ - msg ;length of the string
filename db 'hello.txt'
_start: ;tells linker entry point
mov ecx,5
mov edx,4
call sum
mov [res],eax
mov edx,1 ;message length
mov ecx,res ;message to write
mov ebx,1 ;file descriptor (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel
write_string msg,len
create_file filename
mov [fout],eax
close_file [fout]
call print_msg
mov eax,1 ;system call number (sys_exit)
int 0x80 ;call kernel
sum:
mov eax,ecx
add eax,edx
add eax,'0'
ret
Next i open gdb:
gdb Hello
(gdb) break _start
Function «_start» not defined
¿Compilación de breakpoint pendiente hasta futura cargada de biblioteca compartida? (y or [n]) y
Punto de interrupción 1 (_start) pendiente.
(gdb) run
Starting program: /asm/Hello
9Hello, world!
Hello, world!from another file
[Inferior 1 (process 5811) exited with code 01]
(gdb)
I solved it, i only change position section .data to section .text and the debugger works.I don't know why, but now the gdb take the .start.

Putting a static address into a register with GNU AS (GAS) .intel_syntax?

.intel_syntax noprefix
.global _start
.text
_start:
mov eax, 4
mov ebx, 1
mov ecx, msg
mov edx, 15
int 0x80
mov eax, 1
mov ebx, 14
int 0x80
.data
msg:
.ascii "Hello, World!\n"
I am trying to compile the above code via GNU AS using the following commands:
asad#Arcturus:~/Desktop/ZJNK$ as --32 -msyntax=intel code.S -o code.o
asad#Arcturus:~/Desktop/ZJNK$ ld -m elf_i386 code.o -o a.out
asad#Arcturus:~/Desktop/ZJNK$ ./a.out
asad#Arcturus:~/Desktop/ZJNK$
But I cannot get any output on the terminal. However, the exit code is still readable:
asad#Arcturus:~/Desktop/ZJNK$ echo $?
14
I am using 64-bit Linux and am able to run the above code via nasm after required changes.
What could have gone wrong?
To load the address of msg, use
mov ecx, offset msg

execve shellcode linux segmentation fault

Im trying to run this shellcode but it throws me: "Segmentation fault" error
The shellcode is the following:
shellcode.asm:
global _start
_start:
jmp short ca
doit:
pop ebx
xor eax, eax
cdq
mov byte [ebx+7], al
mov long [ebx+8], ebx
mov long [ebx+12], eax
lea ecx, [ebx+8]
mov byte al, 0x0b
int 0x80
ca:
call doit
db '/bin/sh'
i compile it with : 'nasm -f elf shellcode.asm'
and link it with: ' ld -m elf_i386 -s -o shellcode shellcode.o
I think the error is when I use mov [ebx+x], al/eax/ebx
because when I erase it from the code y get no error
Thank you
Your problem is that the .text section is not writable by default. The easiest thing to do is put your code into a new custom section that is marked as writable. Add this line at the top of your asm file:
section .shellcode progbits alloc exec write align=16
You could also pass the -N switch to the linker.
Alternatively, you could rewrite the shellcode so that it uses the stack to create the arguments.

nasm,86_64,linux,"hello world" program. when link ,it says "relocation truncated to fit"

[section .data]
strHello db "Hello World"
STRLEN equ $-strHello
MessageLength equ 9
Message db "hi!!!! "
[section .text]
global main
main:
mov edx,STRLEN;
mov ecx,strHello;
mov ebx,1
mov eax,4
int 0x80
call DispStr
mov ebx,0
mov eax,1
int 0x80
DispStr:
mov ax,MessageLength
mov dh,0
mul dh
add ax,Message
mov bp,ax
mov ax,ds
mov es,ax
mov cx,MessageLength
mov ax,01301h
mov bx,0007h
mov dl,0
int 10h
ret
Compile and run:
$ nasm -f elf64 helloworld.asm -o helloworld.o
$ gcc -s -o helloworld helloworld.o
helloworld.o: In function `DispStr':
helloworld.asm:(.text+0x31): relocation truncated to fit: R_X86_64_16 against `.data'
collect2: ld return 1
This exact error happens because at:
add ax,Message
ax is only 16-bit wide, but Message is a 64-bit wide address, so it won't fit during relocation.
I have explained this error in detail at: https://stackoverflow.com/a/32639540/895245
The solution in this case is to use a linker script as mentioned at: Using .org directive with data in .data section: In connection with ld
This repository contains working examples of boot sectors and BIOS: https://github.com/cirosantilli/x86-bare-metal-examples/tree/d217b180be4220a0b4a453f31275d38e697a99e0
Since you're in 64-bit mode, you won't be able to use BIOS functions (i.e. the int 10h instruction). Even if you could, BIOS uses a different addressing mechanism, so attempting to use the address of Message wouldn't work anyway.
Also, wouldn't the first 3 lines of the DispStr function zero out ax? (since you're multiplying by dh, which was just set to zero)

Resources