Wednesday, March 14, 2018

Can't Take My Eyes Off You

You're just too good to be true
I can't take my eyes off you
You'd be like heaven to touch
I wanna hold you so much
At long last love has arrived
And I thank God I'm alive
You're just too good to be true
Can't take my eyes off you

Pardon the way that I stare
There's nothing else to compare
The sight of you leaves me weak
There are no words left to speak
But if you feel like I feel
Please let me know that is real
You're just too good to be true
I can't take my eyes off you

I love you baby
And if it's quite all right
I need you baby
To warm the lonely nights
I love you baby

Trust in me when I say

...

Can't Take My Eyes Off You - (Frank Valli)

Friday, March 9, 2018

files

Eu acredito que uma boa parte de vocês encontrem problemas com a inicialização, assim como eu. Por isso proponho uma discussão sobre o assunto.
No meu sistema o boot funciona assim:
>> O primeiro arquivo é o MBR, ele carrega o arquivo BM.BIN na memória e passa o comando para ele, além de passar como argumentos alguns parâmetros de disco. O MBR encontra o BM.BIN do diretório raiz de uma partição formatada em fat16. Isso é feito em 16bit usando recursos do BIOS.
>> O segundo arquivo é BM.BIN, Boot Manager, ele é feito em assembly 16/32bit. Já de cara, ainda em 16bit, usando recursos do BIOS, ele carrega na memória o arquivo BL.BIN, depois faz algumas inicializações em 16bit, muda para o modo protegido, de 32bit, e entra em um mini-shell feito em assembly 32bit, de onde eu posso efetuar comandos para verificar as propriedades de disco e outras coisas. Um dos comandos é o comando 'boot', que retorna para o modo real, muda para o modo gráfico usando VESA e depois comuta para o modo protegido e passa o comando para o arquivo BL.BIN. Além de passar um monte de argumentos para ele como parâmetros do sistema.
>> O terceiro é o BL.BIN, Boot Loader. Ele é feito em C e Assembly 32bit. Quando ele inicializa ele recebe e salva os argumentos, que são muito impotantes. Em seguida passa o comando para a parte em C 32bit, que carregará o KERNEL.BIN e vários outros arquivos, que estejam em um disco IDE formatado em fat16. Faz algumas inicializações de paginação e passa o comando para o Kernel.
>> O quarto é o kernel em si. Falarei detalhadamente sobre ele em outro post. Mas ele é feito em C e Assembly 32 bit. É do tipo híbrido, e contém quatro camadas. Chamadas /hal /microkernel / executive /gramado. A camada /hal é para abstrações de hardware, é a única camada e mexe diretamente com o hardware. A camada /microkernel, faz a inicialização, a comunicação entre processos, o dma e principalmente o gerenciamento de processos e threads. A camada /executive são rotinas de nível superior, longe do hardware, ela oferece rotinas mais elaboradas, principalmente para gerenciamento do sistema. Por último e acima de todas, está a camada /gramado, nela estão os recursos gráficos, as primitivas de suporte para logon, logoff e gerenciamento de usuário.
Por fim, o kernel irá passar o comando para os threads dos processos que estão em user mode e fica rodando esses threads dos processos, seguindo uma ordem de prioridades, ele intercala entre eles, deixando cada thread usar o processador na média por 8 ciclos do timer, cada ciclo tem 10 milisegundos. O thread com mais prioridade fica mais tempo.


Timer

** Timer **
Quanto tempo um thread deve ficar utilizando o processador até que seja substituido por esgotamento de tempo ??
Eu programo meu PIT para operar no modo 3, (geredor de ondas quadradas), gerando uma interrupção a cada 10 milissegundos, ou seja, 100Hz.
Eu troco de thread, na média, a cada 9 interrupções de timer. Dependendo da prioridade do thread. Ou seja, a cada 90 milissegundos.
Eu já vi que um time-slice padrão é 100 ms, mas que pode variar muito dependendo da prioridade.
Quanto tempo devo deixar um thread usando o processador antes de efetuar preempção por tempo ??

Janelas

** Janelas **
Bom, todo mundo aqui sabe que um sistema operacional pode funcionar sem interface gráfica. Não é isso o que eu quero discutir.
***
Pode parecer que lidar com janelas é uma coisa fácil mas não é.
Pra mim, o maior problema em lidar com janelas são as mensagens, isso mesmo, janelas recebem mensagens e são afetadas por essas mensagens e o que afeta a janela pode afetar o processo ao qual ela pertence.
Essas mensagens podem vir de vários lugares. Podem vir do teclado, do mouse, de um toque na tela ou simplesmente enviadas por rotinas de envio de mensagens.
Uma mensagem afeta uma janela específica que normalmente é a janela com o foco de entrada.
Um procedimento de janela é a rotina que recebe essas mensagens e efetua alguma ação de acordo com o número da mensagem.
Desde o começo do projeto é bom que saibamos que os dispositivos de entrada enviarão mensagens que afetarão as janelas. Não importa o tamanho do seu projeto, a questão é que se ele for usar interface gráfica, precisa se preocupar com essa transferência de mensagem entre o driver de dispositivo e o procedimento de janela que irá receber essa mensagem.
Para 'facilitar' a coisa criamos filas de mensagens. A mensagem que saiu do teclado vai parar em alguma fila de mensagens, e as vezes digitamos mais rápido do que a capacidade do aplicativo de processar essas mensagens, então as mensagens vão se enfileirando, esperando cada uma a sua vez.
***
A parte divertida é pintar as janelas, mover as janelas ... isso é mais simples de entender e mais divertido, mas também não é fácil.
Quando o assunto é janela, devemos lembrar que elas consomem muita memória e tempo de processamento.
O tempo que os elementos gráficos demoram para aparecerem na tela é o ponto chave. Esse tempo é afetado por inúmeras variáveis.
Quem deseja fazer um sistema operacional com interface gráfica deve se preocupar com ela desde o início do projeto.

Equilíbrio

** Equilíbrio **
Você não conseguirá fazer um equilíbrio da utilização dos recursos de processamento sem a contagem ...
É preciso contar todo tipo de evento relativo a utilização de recursos de processamento. Coisas como quantos ticks to timer uma thread rodou até ceder a vez para outra thread ou quantos ticks de timer o thread ficou rodando até terminar a execução.
Um aplicativo em user mode pode fazer uma análise dessas estatísticas sobre utilização de recursos de processamento. Para levar o sistema a um equilíbrio.
O primeiro objetivo é conseguir esse equilíbrio ... qualquer problema faz o sistema sair do equilíbrio desejado ... Então o sistema deverá reagir a essa saída do equilíbrio e voltar para o equilíbrio.
Quem será responsável por isso serão serviços utilitários de análise de utilização de recursos de processamento.

taskswitching e scheduler

Uma observação:
Queria iniciar uma conversa sobre a relação taskswitching e scheduler.
>> Taskswitch acontece ao fim do time-slice ou após uma preempção.
>> O scheduler é acionado ao fim do round ou quando a fila de threads que estão prontas pra rodar está vazia.
Atualizando a postagem:
Essa assunto é bem importante e rende muita conversa. Mas basicamente se trata do momento de trocar uma tarefa por outra e do momento de reagendar todas as trocas.

CORES

** CORES **
Trabalhar as cores do sistema é uma coisa segura. Difícil foi fazer com que um aplicativo em user mode pudesse escolher as cores que quer usar.
Eu criei dois esquemas de cores. Um se chama 'humility' com vários tons de cinza e o outro chama "pride", meio verde, cinza e preto.
Preciso aprender sobre design, UI e UX. Alguém tem alguma dica ?!

escrevendo

Vou fazer uma observação um pouco ingênua.
Eu vou escrevendo o meu código e não espero acumular muita coisa, já vou logo compilando e testando o sistema todo pra ver se não vai travar. Porque na prática é assim, uma coisinha errada e trava tudo. Aí pra achar o erro é quase impossível, tenho que desistir da versão.
Talvez seja difícil encontrar o erro porque vira e mexe temos que fazer modificações em pontos distantes um do outro no código.
Quando escrevo alguma coisa pra user mode eu me preocupo menos.
Também é assim com vocês?

Sobre o meu modo gráfico

** Sobre o meu modo gráfico **
Eu implemento o jeito mais simples e barato de obter o modo gráfico ...
Vou comentar aqui para o caso de você desejar utilizar o modo gráfico em seu projeto.
===============================
Em resumo:
Estando em modo protegido de 32bit eu volto para o modo real para configurar o modo gráfico via VESA, retornando em seguida para o modo protegido de 32bit mas agora no modo gráfico.
Toda a memória de vídeo é conhecida como LFB, Linear Frame Buffer. No meu caso são 8 MB.
Eu mapeio 4MB da memória de vídeo, que é mais do que a área visível da memória de vídeo. Na minha resolução, a área visível é de pouco mais de 1MB. Esse pequeno espaço é chamado de frontbuffer. Então sobra mais de 6MB de memória de vídeo.
Eu mapeio 4MB na memória RAM . Mas eu uso pouco mais de 1MB, que é o backbuffer. O equivalente á área visível da memória de vídeo.
Eu desenho as janelas no backbuffer e copio do backbuffer para o frontbuffer.
Eu desenho pequenos elementos gráficos no backbuffer e copio esses elementos no frontbuffer também.
Esse modelo é o mais simples e barato que você vai conseguir implementar. O desempenho não é bom, mas está acessível para qualquer um implementar.
>> Na memória de vídeo:
+Total 8MB.
+Mapeio apenas 4MB.
+Frontbuffer de 1,5MB (área visível)
>>Na memória RAM:
+Mapeio 4MB.
+1,5MB de backbuffer.
Precisando de ajuda é só perguntar.
==========================================
Ouvi dizer que exite um jeito que tanto o backbuffer quando o frontbuffer ficam dentro da memória de vídeo. Daí é só alternar entre eles. Não sei fazer isso ainda. É muito foda, quando vc aprender vc me ensina.

drivers de sistema do tipo persistentes e drivers modulares

A ideia de drivers de sistema do tipo persistentes e drivers modulares me parece muito promissora.
>> O driver de sistema do tipo persistente deverá permanecer na memória o tempo todo, mas pode ser desativado para dar lugar a outro driver.
>> Já os drivers modulares podem ser descarregados da memória para dar lugar a outros drivers ...
...
Drivers de sistema do tipo persistentes combinam com o processo de boot e com a fase de inicialização ....
Ou seja, justamente o que a maioria de nós estamos enfrentando ...
Essa ideia de um drivers persistente porém provisórios facilitam as coisas ...
Nós ainda não temos recursos para usarmos drivers modulares e ficarmos carregando e descarregando drivers ... então para facilitar, podemos criar drivers que sejam considerados do sistema e persistentes ...
No futuro, quando as coisas melhorarem, passaremos a desativar esses drivers de sistema e persistentes e arriscarmos carregar drivers modulares ...
De fato eles poderão co-existirem ... e a gente pode tirar proveito da facilidade que drivers de sistema do tipo persistentes podem nos oferecer.
Poderemos considerar drivers de sistema do tipo persistentes os drivers em user mode, os drivers em kernel mode e até mesmo os drivers dentro do kernel base... isso mesmo , por que não ??
A gente vai usando o driver dentro do kernel base e na primeira oportunidade a gente apenas desabilita ele, dando lugar para o driver modular.
...
depois falo mais. Tá ficando longo.

eventos e mensagens de teclado

Eu estou interessado em aprender sobre eventos e mensagens de teclado ...
Alguém conhece bons projetos para me mostrar.??
A minha maior intenção e ver a mensagem de teclado chegando no procedimento de janela da janela com o foco de entrada.

time-slice

Pelo que vi, o time-slice de um processo deve depender da prioridade, da quantidade de processos rodando, da velocidade de processamento e do modelo de escalonador.
Alguém teria algo pra acrescentar nessa conversa ??

api

Me ajudem, por favor. Tenho um aplicativo em user mode com uma API e uma biblioteca C99 bem magrinhas. Eu faço algumas chamadas ao kernel via 'system call' e uso algumas funções da biblioteca. O que é mais fácil de implementar daqui pra frente? O que vocês fazem nessa parte do sistema?#systemcall #api #bibliotecas

fácil de usar

Tornar o computador mais fácil de usar é sempre uma questão a se pensar pra quem programa.
** Uma pequena reflexão sobre interfaces gráficas. **
O design baseado no tamanho da tela do dispositivo é uma tecnologia efervescente hoje em dia. Tá todo mundo tentando se adaptar às inúmeras possibilidades.
Desde as pequenas telas do IOT até as telas em 3D da VR existe um mar de possibilidades. Mas uma coisa que eu vejo em comum, é que se deve observar o nível de experiência do usuário e ir oferendo mais conteúdo conforme o nível de experiência aumenta.
Simplificar a interface, significa abordar o usuário de menor nível de experiência.
** Threads de usuário X Threads de kernel **
Queria iniciar uma conversa sobre threads.
Conheço dois modelos de gerenciamento de threads. Um é chamado de "threads de usuário" e o outro é chamado de "threads de kernel".
No modelo "threads de usuário" as threads são criadas pelo próprio processo que está rodando em user mode através das bibliotecas de gerenciamento de threads e as informações sobre as threads ficam guardadas em estruturas de dados gerenciadas pelo processo, o kernel não sabe de nada.
No modelo "threads de kernel" as threads são gerenciadas pelo kernel e as estruturas de dados são gerenciadas pelo kernel.
Mas tem um porém. Quando um processo precisa rodar uma thread de usuário no modelo "threads de usuário" ele precisa invocar uma thread de kernel para a thread de usuário que ele deseja rodar.
Daí aparecem termos como "muitos para um", "um para um" e "muitos para muitos".
Bom, isso dá muita conversa 
Segue uma imagem ilustrativa. #thread
** Tá começando a ficar mais fácil esse negócio de alocar páginas para arquivos **



Projeto Pessoal

Meu projeto pessoal de Informática. Você pode ver mais sobre meu projeto pessoal na minha página no Facebook. https://facebook.com/fredno...