Em um computador, você grava em um 'endereço de memória' especificado. Este endereço é reconhecido pelo sistema como um endereço de hardware e o hardware apropriado recebe ou envia o valor apropriado.
A maioria dos sistemas de hardware possui muitos registros diferentes que podem ser configurados ou lidos. Alguns podem ter alguns, alguns podem ter muitos. Esses registros serão agrupados em uma faixa contínua. Um ponteiro base aponta para o primeiro no intervalo e você grava, por exemplo, a segunda porta com base_pointer + 1. Você não precisa, pode escrever diretamente para um ponteiro, mas usar um deslocamento facilita o trabalho das coisas.
O Raspberry Pi reconhece uma enorme variedade de registros de hardware no endereço 0x20000000. Uma variedade de registradores que controlam sistemas de relógio são acessados a partir de BCM2708_PERI_BASE + 0x101000. Os registradores que controlam o relógio I2S são os registradores 38 e 39 desse bloco, gravados usando BCM2708_PERI_BASE + 0x101000 + 0x26 e 0x27
Você não pode simplesmente alterar os valores do relógio, porém, você deve desativar o relógio, alterar os valores e reiniciá-lo.
Se esta resposta é muito básica, minhas desculpas. Nesse caso, sua pergunta é realmente grave, boa sorte. Você pode achar este link útil
Atualização: Por que usar o mmap e não gravar diretamente na memória?
Quando um programa está executando os endereços de memória que acha que não são endereços reais, eles são mapeados para endereços reais pelo gerenciador de memória. Isso impede que um programa possa afetar outro. Dois processos podem ler e gravar em seu próprio endereço 1234 perfeitamente felizes, e o gerenciador de memória manterá os dois locais completamente separados.
As portas de hardware, no entanto, estão em endereços físicos absolutos. Mas você não pode escrever diretamente para eles, porque o gerenciador de memória pega seu endereço e o mapeia para sua área de memória pessoal.
No Linux / dev / mem, há um ' arquivo de dispositivo de caractere que é uma imagem da memória principal do computador '
Se você abrir isso como um arquivo, poderá ler e gravar nele como um arquivo. No exemplo fornecido, mem_fd é um identificador de arquivo resultante da abertura de / dev / mem
Outro sistema que pode facilitar muito a vida é a capacidade de mapear um arquivo na memória e gravá-lo como memória. Portanto, se você possui um arquivo no qual deseja ler ou gravar diferentes bits específicos, em vez de mover o ponteiro do arquivo para trás e para frente, é possível mapeá-lo para um local na memória e gravá-lo diretamente como se fosse memória.
Portanto, neste exemplo, o código está criando um identificador para a memória física, como se fosse um arquivo em disco, e depois pedindo ao sistema para tratá-lo como se fosse memória. Um pouco complicado, mas necessário para contornar o gerenciador de memória virtual e gravar em um endereço físico real. O valor 0x20000000, ao que parece, é um pouco de um arenque vermelho. O código está propondo esse endereço como uma dica, o sistema não precisa mapear / dev / mem aqui, embora provavelmente o faça. Normalmente, o valor nulo seria passado e o sistema mapearia o identificador do arquivo para qualquer endereço que considerasse melhor.
Agora a memória física é mapeada para a memória virtual dos processos, e as leituras e gravações vão para onde você espera.
Referências:
http://www.kernel.org/doc/man-pages/online/pages/man2/mmap.2.html
http://www.raspberrypi.org/phpBB3/viewtopic.php?f=44&t=8496&p=104359
https://superuser.com/questions/71389/what-is-dev-mem