Could someone explain me how the CPU address the secondary storage? If the CPU needs data that are stored on a HDD (for example), could the CPU address the HDD directly? And the data are transfered directly to the CPU or are first copied into RAM? I'm talking about a system without DMA. Thank you
When you say that a system doesn't have DMA, you are talking about very old hardware that isn't very pertinent today.
The newest system without DMA I know of is PIO mode that all ATA (including SATA) drives must support to be compliant (https://wiki.osdev.org/ATA_PIO_Mode).
In PIO mode, the drive is controlled using some IO ports. These are small registers apart from RAM that the CPU writes with some values to trigger read/write cycles. This is why the CPU is involved in the operation. The CPU needs to read an IO port to get the data that have been read. This is as opposed to a system with DMA where the disk controller (AHCI) reads and writes to/from RAM directly.
The AHCI from intel is a PCI device connected to the PCI bus. It is a DMA device. All disk transfers today are DMA
I recommend you read the article about PIO mode (Programmed Input/Ouput) of ATA disks. This article takes you step by step to understand how to address the hard-disk in PIO mode with LBA (Logical Block Addressing).
I'll answer for x86 since I am more aware. Basically, the CPU has special instructions which allow a programmer to output or input data to small registers (IO ports) on the motherboard which have conventional numbers. There instructions are the
in instructions. These instructions have special opcodes in the CPU.
These IO ports are connected to the disk controller of the hard-drive and, when you write certain values to them, the hard-drive reacts in certain ways. For example, you can write 0x24 to IO port 0x1f7 to trigger read/write cycles to/from an any ATA drive with the following:
mov dx, 0x1f7 mov al, 0x24 out dx, al
Once the transfer is complete, an interrupt is fired. The CPU then needs to read a specific IO port several times to transfer the data in one of its registers. It then needs to use a
mov instruction to move the data from the register to RAM. The part in the PIO mode article which does the reading is the following:
.data_rdy: ; if BSY and ERR are clear then DRQ must be set -- go and read the data sub dl, 7 ; read from data port (ie. 0x1f0) mov cx, 256 rep insw ; gulp one 512b sector into edi or dl, 7 ; "point" dx back at the status register in al, dx ; delay 400ns to allow drive to set new values of BSY and DRQ in al, dx in al, dx in al, dx
Again, this is how is used to work. Today, things get more complex. Today, all systems ship with a separate PCI (Peripheral Component Interconnect) compliant chip called AHCI (Advanced Host Controller Interface). The AHCI (https://www.intel.ca/content/www/ca/en/io/serial-ata/serial-ata-ahci-spec-rev1-3-1.html) is a PCI device used to control modern SATA drives. As stated on the link I provided:
This specification defines the functional behavior and software interface of the Advanced Host Controller Interface (ACHI), which is a hardware mechanism that allows software to communicate with Serial ATA devices. AHCI is a PCI class device that acts as a data movement engine between system memory and Serial ATA devices.
The AHCI chip is present on most if not all x86 computers today and is manufactured by Intel. I am pretty confident you have an AHCI on your computer currently and that this is what your OS is using to communicate with your hard-drive. PCI works with MMIO (Memory Mapped IO). When the CPU sets certain lines of its address bus and outputs data on the data bus, it will write the data to PCI devices instead. Basically, you write to some conventional position in RAM to write to the PCI devices.
To find an AHCI, you:
Find the base address of the PCI configuration space using the MCFG ACPI table;
Use the PCI registers there to determine if there are several PCI host controllers. If there is only one, you scan bus 0 only. Otherwise, you scan each function of the first PCI host controller to determine if there is something there and scan the bus associated with the other controllers (most often you will scan only bus 0 because there will be only one host controller). Every PCI device (including host controllers) are present on a PCI bus and each bus can have up to 32 devices and each device can have up to 8 functions. Read my answer here for more info: When are a controller's registers loaded and ready to inform an I/O Operation?
Determine the function is an AHCI by reading the class id and subclass id fields of each function on the buses you find.
Once you found an AHCI, you will read/write to some registers in its configuration space to trigger read/write cycles directly to/from RAM. The AHCI specification is quite simple compared to the xHCI (USB controller). Maybe start by reading it and you'll have a good understanding. Once a transfer is done, the AHCI will trigger an interrupt using the MSI-X capability of PCI devices.