AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 461689
Accepted
rhodeo
rhodeo
Asked: 2018-08-10 15:13:27 +0800 CST2018-08-10 15:13:27 +0800 CST 2018-08-10 15:13:27 +0800 CST

O que o endereço físico 0 no Linux x86 contém?

  • 772

Não tenho certeza se esta pergunta deve ir aqui ou em reverseengineering.stackexchange.com

Citando da Wikipédia :

No processador 8086, a tabela de interrupção é chamada IVT (tabela de vetor de interrupção). O IVT sempre reside no mesmo local na memória, variando de 0x0000 a 0x03ff, e consiste em 256 ponteiros far de modo real de quatro bytes (256 × 4 = 1024 bytes de memória).

Isto é o que eu encontro no monitor qemu:

(qemu) xp/128xw 0
0000000000000000: 0xf000ff53 0xf000ff53 0xf000e2c3 0xf000ff53
0000000000000010: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000020: 0xf000fea5 0xf000e987 0xf000d62c 0xf000d62c
0000000000000030: 0xf000d62c 0xf000d62c 0xf000ef57 0xf000d62c
0000000000000040: 0xc0005526 0xf000f84d 0xf000f841 0xf000e3fe
0000000000000050: 0xf000e739 0xf000f859 0xf000e82e 0xf000efd2
0000000000000060: 0xf000d648 0xf000e6f2 0xf000fe6e 0xf000ff53
0000000000000070: 0xf000ff53 0xf000ff53 0xf0006aa4 0xc0008930
0000000000000080: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000090: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000a0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000b0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000c0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000d0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000e0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000f0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000100: 0xf000ec59 0xf000ff53 0xf000ff53 0xc0006730
0000000000000110: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000120: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000130: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000140: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000150: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000160: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000170: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000180: 0x00000000 0x00000000 0x00000000 0x00000000
0000000000000190: 0x00000000 0x00000000 0x00000000 0xf000ff53
00000000000001a0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000001b0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000001c0: 0xf000d611 0xf000ec4e 0xf000ec4e 0xf000ec4e
00000000000001d0: 0xf000d61a 0xf000d623 0xf000d608 0xf000ec4e
00000000000001e0: 0xf000ff53 0x00000000 0xf000ff53 0xf000ff53
00000000000001f0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53

Não tenho certeza do que fazer com esses valores. Não se parece com uma tabela de descritor de interrupção (desreferenciar esses valores fornece todos os nulos). Então, o que estou realmente olhando aqui?

memory x86
  • 3 3 respostas
  • 2576 Views

3 respostas

  • Voted
  1. Best Answer
    JdeBP
    2018-08-11T03:42:19+08:002018-08-11T03:42:19+08:00

    Qualquer que seja o seu firmware deixou contendo.

    Em um sistema moderno ideal, o processador nunca entra no modo real, como expliquei nesta seção de perguntas e respostas da SU intitulada: Em que modo os chips Intel modernos de 64 bits executam o setor de inicialização? , o primeiro KiB de memória física é tão irrelevante quanto Johan Myréen fez em outra resposta aqui. Mas muitos firmwares modernos (ainda) têm suporte à compatibilidade , o que significa que

    • eles podem retroceder (sim, voltar , dado que passaram diretamente do modo irreal para o modo protegido) do modo protegido para o modo real para executar softwares de sistema escritos para o modo real, como programas de inicialização PC/AT de estilo antigo em MBR e VBR; e
    • eles fornecem as antigas APIs de firmware de modo real e configuram todas as estruturas de dados para essas APIs, nas quais os softwares de sistema mencionados acima dependem.

    Uma dessas estruturas de dados é o modo real IVT. As antigas APIs de firmware de modo real são baseadas em intinstruções, e o IVT de modo real é preenchido pelo firmware como parte de sua inicialização com ponteiros para as várias rotinas de manipulação de firmware para essas instruções.

    Os softwares de sistema de modo protegido não precisam das antigas APIs de firmware de modo real e nunca executam o processador em modo real, portanto, o IVT de modo real nos primeiros 1KiB de memória física não é usado. (O modo protegido v8086 não endereça o endereço físico 00000000 e superior, lembre-se. Ele endereça os endereços lógicos 00000000 e superiores, que são traduzidos por tabelas de páginas.) Em sistemas EFI modernos, o firmware entrega um mapa de memória da memória física ao sistema operacional bootstrap, informando quais partes são reservadas ao firmware para seus próprios propósitos de API de modo protegido e quais partes o sistema operacional está livre para seguir em frente e usar para seu pool de memória física. Em teoria, a primeira página da memória física pode estar na última categoria.

    Na prática, em primeiro lugar, os firmwares geralmente marcam a primeira página da memória física como "código de serviços de inicialização", o que significa que um sistema operacional pode reivindicá-lo e usá-lo como parte de seu pool de memória física, mas somente após a inicialização . os serviços de tempo do firmware EFI foram encerrados pelo sistema operacional e o firmware reduzido para fornecer apenas seus serviços de tempo de execução. Um exemplo disso pode ser visto no log do kernel Linux (com a add_efi_memmapopção) mostrado por Finnbarr P. Murphy:

    [ 0.000000] efi: mem00: type=3, attr=0xf, range=[0x0000000000000000-0x0000000000001000) (0MB)
    que xe decodifica com outro programa em uma forma mais legível como:

    [#00] Tipo: EfiBootServicesCode Attr: 0xF
          Físico: 0000000000000000-0000000000001000
          Virt: 0000000000000000-0000000000001000

    Na prática, em segundo lugar, o Linux ignora explicitamente essa faixa de memória física, mesmo que o firmware diga que pode ir em frente e usá-la. Você descobrirá que em firmwares EFI e não EFI, uma vez que o Linux tenha o mapa de memória física, ele o corrige ( em uma função chamadatrim_bios_range ), resultando em mensagens de log do kernel, como:

    [ 0.000000] e820: atualização [mem 0x00000000-0x00000fff] utilizável ==> reservado

    Isso não é tanto para lidar com firmwares EFI modernos, onde o modo real IVT não faz parte da API de firmware, mas sim para lidar com firmwares PC98 antigos, onde faz parte da API de firmware, mas os firmwares o relatam (via essa mesma API) como memória física disponível para ser sobrescrita pelo sistema operacional.

    Assim, embora em teoria esse intervalo de memória física possa conter código ou dados arbitrários, dependendo das necessidades momentâneas dos alocadores de memória do kernel e da memória virtual paginada por demanda; na prática, o Linux simplesmente o deixa intocado como o firmware o configurou originalmente.

    E em seu sistema, o firmware o preencheu com entradas IVT de modo real. As entradas IVT de modo real são apenas ponteiros far 16:16, é claro, e se você observar sua memória usando um hexdump de 2 bytes, poderá ver isso claramente. Alguns exemplos:

    • A maioria de suas entradas IVT apontam para F000:FF53, um endereço na área de ROM de firmware de modo real. Provavelmente é uma rotina fictícia que não faz nada além de um arquivo iret.
    • A entrada IVT 1E aponta para F000:6AA4, uma tabela na mesma área ROM.
    • A entrada IVT 1F aponta para C000:8930, uma tabela na área de firmware de ROM de vídeo em modo real.
    • A entrada IVT 43 aponta para C000:6730, outra tabela na área de firmware de ROM de vídeo em modo real.

    Leitura adicional

    • Finnbarr P. Murphy (2012-08-18). Memória UEFI V Memória E820 . fpmurphy. com.
    • Em que modo os modernos chips Intel de 64 bits executam o setor de inicialização?
    • 10
  2. Johan Myréen
    2018-08-10T23:01:47+08:002018-08-10T23:01:47+08:00

    A arquitetura original do processador 8086 (implementada como Modo Real em processadores 80286+) não tem relevância para o Linux, que opera em Modo Protegido. Não há nenhuma tabela de vetores de interrupção no endereço físico 0, em vez disso é usada uma Tabela de Descritores de Interrupção contendo Descritores de Interrupção. O IDT pode ser localizado em qualquer lugar na memória.

    O kernel do Linux obtém um mapa de memória física do firmware (BIOS ou EFI) que informa quais quadros de página de memória física podem ser usados ​​e quais estão reservados ou não estão presentes. O intervalo de quadros de página utilizáveis ​​não é contíguo, mas normalmente possui grandes buracos. Tradicionalmente, o kernel Linux x86 pulou o início da memória física, mesmo que esteja marcado como utilizável. Assim, o endereço físico 0 não é usado pelo kernel do Linux.

    • 7
  3. slm
    2018-08-10T16:15:42+08:002018-08-10T16:15:42+08:00

    Despejando memória

    Aqui está uma maneira alternativa de despejar o conteúdo da memória dentro do sistema em vez de fazer isso externamente:

    $ head /dev/mem | hexdump -C
    00000000  53 ff 00 f0 53 ff 00 f0  53 ff 00 f0 53 ff 00 f0  |S...S...S...S...|
    00000010  53 ff 00 f0 53 ff 00 f0  cc e9 00 f0 53 ff 00 f0  |S...S.......S...|
    00000020  a5 fe 00 f0 87 e9 00 f0  53 ff 00 f0 46 e7 00 f0  |........S...F...|
    00000030  46 e7 00 f0 46 e7 00 f0  57 ef 00 f0 53 ff 00 f0  |F...F...W...S...|
    00000040  22 00 00 c0 4d f8 00 f0  41 f8 00 f0 fe e3 00 f0  |"...M...A.......|
    00000050  39 e7 00 f0 59 f8 00 f0  2e e8 00 f0 d4 ef 00 f0  |9...Y...........|
    00000060  a4 f0 00 f0 f2 e6 00 f0  6e fe 00 f0 53 ff 00 f0  |........n...S...|
    00000070  ed ef 00 f0 53 ff 00 f0  c7 ef 00 f0 ed 57 00 c0  |....S........W..|
    00000080  53 ff 00 f0 53 ff 00 f0  53 ff 00 f0 53 ff 00 f0  |S...S...S...S...|
    ...
    ...
    000afea0  00 00 00 00 00 00 00 00  aa aa aa 00 aa aa aa 00  |................|
    000afeb0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    *
    000b0000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
    *
    000c0000  55 aa 40 e9 62 0a 00 00  00 00 00 00 00 00 00 00  |[email protected]...........|
    000c0010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 49 42  |..............IB|
    

    Análise

    A parte superior acima de 000c0000 pode estar relacionada ao bootloader. Por que eu suspeitaria disso? O código 55aah no local 000c0000normalmente pode ser uma marca na memória para coisas como um gatilho para o BIOS executar um carregador de inicialização secundário.

    Referência: Assinatura de inicialização - BIOS

      ss#1

    No entanto, dado que este 55aah ocorre na faixa c0000h-effffh, é mais provável que esta parte seja o cabeçalho de expansão PNP:

    Referência: Especificação de inicialização do BIOS

    3.3 Dispositivos com Cabeçalhos de Expansão PnP

    Todos os dispositivos IPL com ROMs opcionais devem conter um cabeçalho ROM opcional válido que resida entre os endereços de memória do sistema C0000h e EFFFFh em um limite de 2k e comece com 55AAh. A inicialização de um dispositivo só pode ser controlada se tiver um cabeçalho de expansão PnP. O Cabeçalho de Expansão, cujo endereço reside no cabeçalho ROM opcional padrão no deslocamento +1Ah, contém informações importantes usadas para configurar o dispositivo. Ele também contém ponteiros para codificar na ROM de opção do dispositivo (BCV ou BEV) que o BIOS chamará para inicializar a partir do dispositivo. Consulte o Apêndice A para a estrutura do cabeçalho de expansão PnP. Há duas maneiras de inicializar um dispositivo IPL com um cabeçalho de expansão PnP. Deve conter um BCV ou um BEV.

    53ss...

    Quanto aos dados 53ffh que estão no início. Não está claro para mim o que isso realmente é. Pesquisando ainda mais, é provável que seja algo que o kernel do Linux escreveu lá depois que o bootloading do MBR do BIOS foi entregue ao kernel do Linux para inicializar.

    Normalmente, o bootloader carregará o kernel na memória e, em seguida, pulará para o kernel. O kernel poderá então recuperar a memória usada pelo bootloader (porque já executou seu trabalho). No entanto, é possível incluir o código do sistema operacional no setor de inicialização e mantê-lo residente após o início do sistema operacional

    Cavando mais, consegui encontrar este parágrafo de um trabalho de pesquisa intitulado: Injeção de código malicioso via /dev/mem :

    1 O dispositivo mem

    /dev/mem é a interface do driver para a memória endereçável fisicamente. A intenção original de mem e kmem era ajudar na depuração do kernel. Podemos usar o dispositivo como um dispositivo de caractere normal, usando lseek() para selecionar um deslocamento de endereço. O dispositivo kmem é semelhante, mas fornece uma imagem da memória do kernel no contexto de endereçamento virtual. O servidor Xorg faz uso do dispositivo mem para acessar a memória de vídeo VESA, bem como a tabela de vetores de interrupção (IVT) do BIOS ROM localizada no endereço físico 0x00000000 para manipular os modos de vídeo no modo VM86. O DOSEMU também usa isso para acessar o BIOS IVT para poder fazer interrupções do BIOS para várias tarefas (leituras de disco, impressão no console, etc).

    Referências

    • Como despejar a imagem da memória do sistema linux?
    • Como despejo a memória física no Linux?
    • Registro mestre de inicialização
    • Compaq Computer Corporation Phoenix Technologies Ltd. Intel Corporation BIOS Boot Specification Versão 1.01 11 de janeiro de 1996
    • Análise de memória Linux - wiki forense
    • X86 Assembly/Bootloaders
    • 4

relate perguntas

  • Quando o heap é usado para alocação dinâmica de memória?

  • Operação de limpeza de RAM sem reinicialização

  • Alto uso de memória de "git status -z -u"?

  • Programa de monitoramento de recursos de memória

  • Um processo pode alocar memória cache de forma que o kernel possa aproveitá-la quando necessário?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    ssh Não é possível negociar: "nenhuma cifra correspondente encontrada", está rejeitando o cbc

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    Como descarregar o módulo do kernel 'nvidia-drm'?

    • 13 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add retorna com: "Erro ao conectar ao agente: nenhum arquivo ou diretório" 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya Por que o Linux usa LF como caractere de nova linha? 2017-12-20 05:48:21 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve