He is nicknamed “the disc surgeon” or “Disk Destroyer” (There is no verification question if you want to run the command)

Be careful when using dd; you can erase everything, including your operating system

It is a low-level tool that copies data byte by byte

Unlike a cp (copy) command, which understands “files” and “folders”, dd understands “blocks” and “physical positions”

dd takes a data stream from an input (if = Input File), processes it (if you ask it to) and writes it to an output (of = Output File)


dd if=/dev/zero of=hola_mundo.img bs=512 count=1
  • if=/dev/zero: This is a kernel virtual drive that only outputs zeros (0x00)
  • of=hola_mundo.img: The destination file
  • bs=512: Block Size. Defines that the size of each data “brick” is 512 bytes (the standard size of a disk sector)
  • count=1: Tells it to copy only one block
  • Result: You created a file of exactly 512 bytes filled with zeros. It’s like buying a vacant lot to build your bootloader
  • The new file is created (or modified) exactly where you are standing in the terminal
  • If you want to know the exact path, type the pwd command before running dd
  • If you want to save it elsewhere, you need to specify the full path in the of command:
  • of=/home/user/projects/kernel/hello_world.img
  • Make sure both the .bin and .img files are in the same folder so the command is short
  • If the destination file does not exist, it creates it

If you are using an ESP (FAT32) partition mounted somewhere, you could do the following:

sudo dd if=hola_mundo.bin of=/mnt/usb_esp/EFI/BOOT/BOOTX64.EFI conv=notrunc

dd if=hola_mundo.bin of=hola_mundo.img bs=512 conv=notrunc
  • if=hola_mundo.bin: Your compiled boot code (your opcodes)
  • of=hola_mundo.img: The file we created previously in before step
  • bs=512: Maintains block consistency
  • conv=notrunc: This is vital. It means “do not truncate.” It tells dd: “Don’t overwrite what’s already in the output file, only write over the first few bytes”
  • Result: Now your .img file has your code in the first few bytes, but maintains its original size (or the rest of the data it contained)
  • Thanks to conv=notrunc, the rest of the hola mundo.img file remains intact. Only the beginning is “patched”

The file size is 512 bytes; the first bytes are the program, then there is padding of 00s (zeros) that do not modify the size and is located in the first sector (boot sector) for a bootloader, for example.


  • if / of: Source and destination
  • bs: Block size (you can use 1M for 1 Megabyte, or 512 for a sector)
  • seek=N: Skip N blocks in the destination before writing (useful to avoid overwriting the partition table)
  • skip=N: Skip N blocks in the source before starting to read

  • The computer starts reading from position 0 to N, from left to right
  • You should visualize the programs as a strip of numbers 0 and 1, where you start reading from the left
  • In devices such as hard drives or USB flash drives, data is read starting from a sector (sector 0), from left to right; it is a long strip of data (0s and 1s)
  • In binary, 0 and 1 (1 bit) would be booleans; to simplify and better understand binary numbers, they are written in hexadecimal (grouping 4 bits, for example: 1011)
  • A hexadecimal digit ranges from 0,..,9,A,..,F (each digit is a group of 4 bits from 0000 to 1111, there are 16 possibilities)
  • 1 bit What does it contain?: It can only be a 0 or a 1. It’s like a switch: on or off
  • Bit symbol: “b” (lowercase)
  • bit and byte are different things
  • 1 byte: It is a group of 8 bits
  • Having 8 positions of zeros and ones (2^8), it can represent 256 different combinations (from 0 to 255)
  • Byte symbol: “B” (uppercase)
  • Sector 0 (MBR): measures 512 Bytes (4096 bits)
  • In hexadecimal: One byte is represented by two letters/numbers (example: 0xFF). That’s why in hexadecimal editors you see files in pairs
  • Bit: Single switch (0 or 1)
  • Byte: A group of 8 switches. It’s the unit we use to measure files and memory
  • If you see a 1 KB file, it’s not 1,000 bits, it’s 1,024 bytes
  • dd uses K for 1024 and KB for 1000 (At a low level, those 24 bytes of difference can cause a bootloader not to fit in the sector)