Que tipo de endereços de memória são mostrados por proc/ioports e proc/iomem?

Que tipo de endereços de memória são mostrados por proc/ioports e proc/iomem?

Sendo a saída de cat proc/ioports:

0000-001f : dma1
0020-0021 : pic1
0040-0043 : timer0
0050-0053 : timer1
0060-0060 : keyboard
0064-0064 : keyboard
0070-0071 : rtc0
0080-008f : dma page reg
00a0-00a1 : pic2
00c0-00df : dma2
00f0-00ff : fpu
0170-0177 : 0000:00:0f.1
  0170-0177 : pata_via
01f0-01f7 : 0000:00:0f.1
  01f0-01f7 : pata_via
0290-0297 : pnp 00:07
02f8-02ff : serial
0376-0376 : 0000:00:0f.1
  0376-0376 : pata_via
0378-037a : parport0
037b-037f : parport0
03e0-03e7 : pnp 00:08
03f2-03f2 : floppy
03f4-03f5 : floppy
03f6-03f6 : 0000:00:0f.1
  03f6-03f6 : pata_via
03f7-03f7 : floppy
0400-041f : pnp 00:08
  0400-0407 : vt596_smbus
04d0-04d1 : pnp 00:08
0778-077a : parport0
0800-087f : pnp 00:08
  0800-0803 : ACPI PM1a_EVT_BLK
  0804-0805 : ACPI PM1a_CNT_BLK
  0808-080b : ACPI PM_TMR
  0810-0815 : ACPI CPU throttle
  0820-0823 : ACPI GPE0_BLK
0cf8-0cff : PCI conf1
d000-d0ff : 0000:00:11.5
  d000-d0ff : VIA8237
d400-d41f : 0000:00:10.3
  d400-d41f : uhci_hcd
d480-d49f : 0000:00:10.2
  d480-d49f : uhci_hcd
d800-d81f : 0000:00:10.1
  d800-d81f : uhci_hcd
d880-d89f : 0000:00:10.0

e a saída de cat /proc/iomem:

00000000-0000ffff : reserved
00010000-0009fbff : System RAM
0009fc00-0009ffff : reserved
000a0000-000bffff : Video RAM area
000c0000-000cf7ff : Video ROM
000e0000-000fffff : reserved
  000f0000-000fffff : System ROM
00100000-bffbffff : System RAM
  01000000-01538f03 : Kernel code
  01538f04-017c217f : Kernel data
  01877000-0194dfff : Kernel bss
bffc0000-bffcdfff : ACPI Tables
bffce000-bffeffff : ACPI Non-volatile Storage
bfff0000-bfffffff : reserved
cff00000-dfefffff : PCI Bus 0000:01
  d0000000-d7ffffff : 0000:01:00.0
e0000000-efffffff : PCI MMCONFIG 0000 [bus 00-ff]
  e0000000-efffffff : pnp 00:0d
f0000000-f7ffffff : 0000:00:00.0
fca00000-feafffff : PCI Bus 0000:01
  fd000000-fdffffff : 0000:01:00.0
  feae0000-feafffff : 0000:01:00.0
febc0000-febdffff : 0000:00:0d.0
  febc0000-febdffff : e1000
febf0000-febf7fff : 0000:00:0a.0
  febf0000-febf7fff : 0000:00:0a.0
febfbc00-febfbcff : 0000:00:10.4
  febfbc00-febfbcff : ehci_hcd
fec00000-fec00fff : reserved
  fec00000-fec003ff : IOAPIC 0
fecc0000-fecc03ff : IOAPIC 1
fee00000-fee00fff : Local APIC
  fee00000-fee00fff : pnp 00:09
ff7c0000-ffffffff : reserved
  fff80000-ffffffff : pnp 00:0e

Não entendo quais endereços de memória estão sendo mencionados aqui. É memória virtual? Seria possível acessar esses endereços de memória a partir de um programa de usuário para, por exemplo, escrever na porta serial? Talvez usando assembler?

Responder1

quais endereços de memória estão sendo mencionados aqui. É memória virtual?

Parte do design do primeiro IBM PC era usar alguns endereços de memória para outras coisas além da memória real (do tipo usado por programas e dados).

No primeiro IBM PC, você poderia ter até 640 KB de RAM, mas os chips poderiam endereçar até 1.024 KB de memória; no entanto, gravar em endereços de memória superiores a 640 (e menores que 1.024) seria na verdade usado para comunicação não com RAM mas com dispositivos como adaptadores gráficos plug-in.

Às vezes, esse conceito é chamado de E/S mapeada em memória ou dispositivos de hardware mapeados em memória.

Mapa de memória do PC

As portas IO são outro tipo de recurso endereçável na arquitetura IBM PC. Antigamente, você configurava fisicamente esses endereços em placas plug-in (ISA) usando "jumpers" para conectar pinos de endereçamento na placa. Você também pode configurar o software para usar endereços de E/S correspondentes.

Uma antiga placa de porta paralela ISA

As letras brancas à esquerda da placa descrevem quais posições de jumper fornecem quais endereços de porta IO, etc.

Hoje em dia, os detalhes de endereçamento são negociados e atribuídos dinamicamente pelas placas e pelo computador host à medida que o sistema é inicializado. Não precisamos mais configurá-los.

Seria possível acessar esses endereços de memória a partir de um programa de usuário para, por exemplo, escrever na porta serial? Talvez usando assembler?

Acredito que sim, supondo que você esteja usando um sistema operacional que permita isso (por exemplo, PC-DOS, um sistema operacional de modo real). Em contraste, os sistemas operacionais modernos em modo protegido impedirão que tais operações sejam bem-sucedidas por um programa do usuário.

Responder2

/proc/ioportslista intervalos de endereços de portas de E/S.

/proc/iomemlista intervalos de endereços de memória física.

Você pode acessar endereços de memória física diretamente de um programa de usuário mapeando /dev/mem, mas provavelmente não deseja. Você pode acessar portas de E/S diretamente de um programa de usuário com ioperm, mas provavelmente não deseja. Geralmente, você realmente deseja estar no modo kernel para fazer esse tipo de coisa porque precisa fazer coisas como desabilitar interrupções.

Responder3

É físico, mas alguns deles são mapeados linearmente para a memória virtual.

informação relacionada