É melhor não fazer várias perguntas de uma só vez, pois nem todos podem ou vão responder a tudo. Ainda assim, vou dar uma resposta curta para cada um.
Does the Linux kernel internally operate with virtual or physical addresses? What especially confuses me is that there are several types of addresses (logical, virtual, bus and physical) and they are all valid and operable by the kernel.
Sim. Partes diferentes do kernel usam diferentes espaços de endereçamento.
Enquanto o código do kernel está processando uma chamada de sistema, seus mapeamentos de memória incluem todo o espaço de memória do kernel e todo o espaço de memória do processo (a menos que seu kernel tenha alta memória configurada, mas é muito complicado entrar aqui). Esses são todos endereços lógicos (também conhecidos como virtuais): os bits de alta ordem do endereço indicam qual página procurar na MMU , e os bits de baixa ordem são um endereço linear dentro da página. Os mapeamentos de memória dentro da MMU mudam sempre que ocorre uma alternância de tarefas (a alteração da tabela de páginas na MMU é uma grande parte de uma alternância de tarefas).
Alguns drivers de dispositivo precisam manipular os endereços de memória válidos para o dispositivo que estão dirigindo. Geralmente são endereços físicos, embora algumas arquiteturas possuam um IOMMU para que os dispositivos também vejam endereços lógicos próprios. É claro que o subsistema de gerenciamento de memória no kernel precisa manipular muitos tipos diferentes de endereços.
Is that correct that CPU instructions can't directly address data stored in peripheral devices and therefore addressable memory is used, i.e. buffers, for these purposes?
Isso é dependente da arquitetura. A maioria das arquiteturas tem algum tipo de DMA (acesso direto à memória) , que permite que pelo menos alguma comunicação com dispositivos seja feita via RAM. Além disso, em algumas arquiteturas (por exemplo, ARM), todos os acessos a dispositivos são feitos com instruções de carga e armazenamento em endereços apropriados, enquanto outros (por exemplo, i386) têm instruções específicas do processador para essa finalidade. Consulte E / S mapeada pela memória para obter mais detalhes.
Can a process sleep when requesting a semaphore (which has a value 0) and has to wait for it?
Sim, usar um semáforo ( down
e amigos) é uma operação de bloqueio. Isso é bem explicado no livro.
Atomic operations -- are these guaranteed by specific CPU instructions?
Sim. Os detalhes são muito específicos da arquitetura. Todas as plataformas destinadas a multitarefa fornecem pelo menos uma primitiva atômica para sincronização, como compare-and-swap , < href="http://en.wikipedia.org/wiki/Test-and-set"> teste-e-definir , load-link + store-condicional , etc. Além de usar a primitiva correta, o código pode precisar tomar o cuidado de usar corretamente memória barreiras em sistemas multiprocessadores. O kernel do Linux fornece uma implementação de suas primitivas de sincronização para cada arquitetura suportada, de modo que você, por sua vez, só precisa usar as primitivas portáveis do kernel.