Advertisement
Haydot

Boot sector with disk reading

Oct 12th, 2021
2,329
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ;This should exist in a new .asm file so that we don't make the boot sector file unreadable
  2. [bits 16] ;Telling our assembler that this code should be written in 16 bits in case this file get written below some 32 bit code !
  3. load_disk: ;Reading the disk
  4.     push dx ;Push dx onto the stack
  5.     mov ah, 0x02 ;putting BIOS in reading sector mode
  6.     mov al, dh ;Putting the number of sectors we will be reading in al so that we can check if everything went ok later
  7.     mov ch, 0x0 ;Read cylinder 0 (if we want to be more accurate, we are actually selecting cylinder 0 and reading from there, not reading everything from it)
  8.     mov dh, 0x0 ;Selecting head 0
  9.     nov cl, 0x2 ;Now we actually do the reading. Or we are still selecting, but we choose what to read. We read sector 2 aka the one after our boot sector
  10.     int 0x13 ;BIOS interupt for reading sectors from the disk
  11.     jc disk_error ;Check if any errors happend along the way and go to our disk error managment function to manage it
  12.     pop dx ;Return dx from the stack
  13.     cmp al, dh ;Check if the sectors we read are equal to the sectors we wanted to read
  14.     jne sector_error ;If not, we jump to our sector error managment function
  15.     ret ;Otherwise, we return
  16. disk_error: ;Disk error managment function
  17.     mov bx, disk_error_message ;Moving our disk error string into bx as an argument for the printing function
  18.     call print_string ;Calling the print string function
  19.     jmp $ ;Hanging in one place, I know this isnt the best way to manage this, but we currently dont have a kernel nor a shell for the user to use to fix or check the error so this is the best we got for now
  20. sector_error: ;Sector error managment function
  21.     mov bx, sector_error_message ;Moving our sector error string into bx as an argument for the printing function
  22.     call print_string ;Calling our printing function
  23.     jmp $ ;Hanging in one place
  24. disk_error_message: db 'Something went wrong while reading the disk...OS exiting with code 0xdec1', 0 ;Our disk error string
  25. sector_error_message: db 'Something went wrong while reading the second sector...OS exiting with code 0xdec2', 0 ;Sector error string
  26.    
  27. ;To link this to our boot sector file, we edit the boot sector in the folowing way:
  28. ;Boot_sector.asm or whatever your is called
  29.  
  30. [bits 16] ;Tell nasm that this code should be written in 16 bits !
  31. [org 0x7c00] ;Tell BIOS where our boot sector should be loaded (the boot sector lays in between the adresses starting from 0x7c00 to 0x7e00)
  32. mov [BOOT_DRIVE], dl ;BIOS will keep our boot drive in the dl register
  33. mov bp, 0x9000 ;Place the start of the stack very far away from BIOS files so that we don't overwrite them.
  34. mov sp, bp ;Same thing here
  35. mov bx, 0x9000 ;Loading the read sectors to the following memory addreses: from 0x0000, to 0x9000
  36. mov dh, 5 ;Reading 5 sectors
  37. mov dl, [BOOT_DRIVE] ;Putting boot drive in dl
  38. call load_disk ;Calling our disk read function
  39. mov bx, msg ;Using the register bx as an argument to our print_string function. We put the value of msg in bx
  40. call print_string ;Call our function for printing strings
  41. jmp $ ;Jump to the current adress AKA hanging in one place
  42. %include "{Path to the disk load file}.asm" ;This, when assembled, gets overwritten by all the code in the file we specified, meaning it acts as if it was always written here and not in a different file. !
  43. BOOT_DRIVE: db 0 ;Asigning out boot drive variable
  44. print_string: ;Start of our print string function
  45.     pusha ;Push all registers to the stack
  46. char_loop: ;In this function, we loop through every byte in bx and print it, ending when there are no bytes left
  47.     mov al, [bx] ;Move the next byte into al
  48.     cmp al, 0 ;Check if there is a byte
  49.     jne char_print ;If there is, we print the char
  50.     popa ;If there isn't, we retrieve all registers from the stack
  51.     ret ;And return to our main loop
  52. char_print: ;Printing individual chars
  53.     mov ah, 0x0e ;Enabling BIOS Tele-type mode
  54.     int 0x10 ;Calling BIOS interupt for printing to screen, equvialent to, in python: 'print(al)'; Interupts are special functions in lower-level programming which when called stop all processes on the pc, do what they must do and let the pc continue it's work
  55.     add bx, 1 ;Moving to the next adress AKA next char in bx
  56.     jmp char_loop ;Going back to the char loop
  57. msg: db 'Hello world!', 0 ;Making a variable called 'msg' that holds databytes given to it by the db(declare byte(s)). In it's current state it's a char, not a string, so we have to tell the router when to stop printing, which we do witj the ', 0'
  58. times 510-($-$$) db 0 ;Pad the file with zeros 510 times !
  59. dw 0xaa55 ;The last two bytes tell BIOS that this is a boot sector and that it should boot it !
  60.  
  61. ;All lines that have a '!' at the end of their comments are only read by the assembler and are deleted while assembling.
  62.  
  63. ;So lets talk a little bit about what does it mean for our boot sector file to be 512 bytes only. It means that in it, we can only have 512 symbols or bytes. This is problematic, as a boot sector can be more then 512 symbols long, especially if we decide to do extra stuff. The solution to that is to add more space to it by reading the disk and adding some extra memory to our file which should be more then enough for what we need. We will use one of the first addreses that get loaded by our function, which are 0xdada and 0xface, with each being 256 bytes, meaning our boot sector will have a new capacity of 1028 bytes.
  64.  
  65. times 256 dw 0xdada ;Adding 0xdada
  66. times 256 dw 0xface ;And 0xface
  67.  
  68.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement