Настольная книга компьютерного исследователя


MenuetOS или еще одна «История Игрушки»

Изначально я планировал сделать более-менее подробный обзор этой операционной системы, но так как информации по ней более чем достаточно, то было решено ограничиться небольшим описанием.

История этой операционки уходит корнями в далёкий 2000 год, когда идея о создании своей ОС пришла в голову и воплотилась руками финского студента по имени Ville Turjanmaa. MenuetOS (далее для простоты MeOS) написана полностью на 32-х битном ассемблере, работает в защищённом режиме (а в каком же ещё), имеет достаточно развитое и, что самое приятное, простое графическое API (тот же MFC отдыхает), поддерживающее VESA v.1.0 и v.2.0. В ядре уже есть дрова для сетевух (rtl преимущественно), всяких мышек, звуковух и тд, короче говоря, MeOS имеет в себе достаточно средств для создания нормальных софтин. Не менее приятный момент состоит в размере MeOS: с большинством приложений вся она легко умещается на 3,5″ дискете. Стоит отметить, что хоть MeOS и написана на чистом асме, проги для неё можно писать не только на нем асме, но и на других языках.

В качестве файловой системы в MeOS используется FAT32. Минимальные средства разработки: TinyPad — текстовый редактор и FASM — Flat Assembler [3]. Этого вполне достаточно, чтобы написать полноценную прогу.

Работа приложения в MeOS основана на событиях, т.е. по схеме: 1) ждём события 2) читаем тип события 3) реагируем на него (или не реагируем)

Всё очень просто. В программе неплохо иметь три основных обработчика событий: перерисовка окна, нажатия на клавиши, «нажатия» на кнопки приложения. Т.е. структура минимального приложения:

 +-->---->---+
 |           |
 |  ┌──────────────────┐
 |  │ wait until event │
 |  └──────────────────┘
 ^           |
 |  ┌──────────────────┐             ┌──────────────────┐
 |  │ is redraw event? │ -- true --> │   redraw screen  │ -+
 |  └──────────────────┘             └──────────────────┘  |
 |           |                                             |
 |  ┌──────────────────┐             ┌──────────────────┐  |
 |  │  is key pressed? │ -- true --> │   process keys   │ -+
 |  └──────────────────┘             └──────────────────┘  |
 |           |                                             |
 |  ┌──────────────────┐             ┌──────────────────┐  |
 ^  │is button pressed?│ -- true --> │ process buttons  │ -+
 |  └──────────────────┘             └──────────────────┘  |
 |           |                                             |
 +----<---<--+--------------------<-------------------<----+

process keys — обработка нажатий кнопок на клавиатуре; process buttons — обработка нажатий кнопок окна приложения; самая простая «реакция» — закрытие приложения.

Системные вызовы в MeOS осуществляются через 0х40 прерывание. От «Hello, world!» уже просто тошнит. В качестве примера я портанул свои трёхмерные звёзды, которые изначально были написаны мною ещё во времена MS DOS, и впоследствии переписаны для MeOS. И просто, и смотрится более интересно. :)

В принципе, в создании прог для MeOS нет ничего сложного, особенно для тех, кто в далёком детстве писал для той же MS DOS или для другой ОС на асме. Любителям же С++ и прочих языков высокого уровня будет немного посложнее сначала, но мы ведь не ищем лёгких протоптанных путей. ;)

В начале моего знакомства с MeOS меня удивил тот факт, что приложения типа FASM, TinyPad и прочие выглядят как-то не так. ;) Вернее, они выглядят хорошо до тех пор, пока не попытаться развернуть окно приложения на весь экран. Вот тут и вылезают «косячки». Они некритичны в работе, но оставляют неприятное впечатление. Кнопка «закрыть», которая находится в правом верхнем углу остаётся на том же расстоянии от левого верхнего угла окна. Очень некрасиво смотрится, когда начальная ширина окна была, скажем, 300 пикселей, и при «разворачивании» его на весь экран на серединке «шапки» окна красуется кнопочка «закрыть». Меня это дело меня не устраивало и я решил это исправить. Вот пример отрисовки кнопки закрыть из стандартных приложений в MeOS:

		                   ; CLOSE BUTTON		                   

        mov  eax,8                 ; function 8 : define and draw button
        mov  ebx,(300-19)*65536+12 ; [x start] *65536 + [x size]
        mov  ecx,5*65536+12        ; [y start] *65536 + [y size]
        mov  edx,1                 ; button id
        mov  esi,0x6677cc          ; button color RRGGBB
        int  0x40

Это кусок из стандартного примера (example.asm) в MeOS, написанный Вилле. Как мы видим, х-координата кнопки фиксированна — (300-19)=281-ый пиксель от начала окна. При изменении ширины окна с трёхсот пикселей до 600 кнопка «закрыть» будет рисоваться на том же месте (281,5).

 

На самом деле, реализация нормального окна с не съезжающими кнопками несложная задача. Я не знаю, по какой причине авторы других программ этот дефект не исправили. Возможно, из-за природной лени — «работает — и хорошо», или из-за того, что в example.asm, который, судя по всему, брался за основу, этого нет. Итак, для того, чтобы узнать ширину окна, нам нужна информация о текущем процессе. Получить её можно так:

 get_process_info:
        mov  eax,9                 ; получить информацию о процессе
        mov  ebx,PInfo             ; указатель на буфер, по которому
                                   ; будут записаны данные о процессе
                                   ; (1024 байта)
        mov  ecx,-1                ; получить информацию о текущем процессе
        int  0x40

Кстати, в описание этой функции в официальной документации вкралась маленькая опечатка. Кто найдёт, тот молодец ;) Теперь, зная информацию о процессе, можно смело создавать окно и не бояться, что кнопка «съедет»:

 draw_window:

    mov  eax,12                    ; функция 12: сообщаем о том, что будем
                                   ; рисовать окно.
    mov  ebx,1                     ; 1, начало отрисовки
    int  0x40

    mov  eax,0                       ; функция 0 : определить и нарисовать окно
    mov  ebx,100*65536               ; [x start] * 65536
    add  ebx,[process_window_width]  ; добавим ширину окна
    mov  ecx,100*65536               ; [y start] * 65536
    add  ecx,[process_window_height] ; добавим высоту окна
    mov  edx,0x02000000              ; определим цвет окна,
    mov  esi,0x805080d0              ; "шапки"
    mov  edi,0x005080d0              ; бордюра
    int  0x40
                               ; заголовок окна
    mov  eax,4                     ; функция 4 : печать текста в окне
    mov  ebx,8*65536+8             ; [x start] * 65536 + [y start]
    mov  ecx,0x00ddeeff            ; шрифт 0 и цвет ( 0xF0RRGGBB )
    mov  edx,labelt                ; адрес начала текста
    mov  esi,labellen-labelt       ; длина текста
    int  0x40
                               ; кнопка "закрыть"
    mov  eax,8                      ; функция 8: определить и нарисовать кнопку
    mov  ebx,[process_window_width] ; ширина окна
    sub  ebx,19                     ; -19
    shl  ebx,16                     ; * 65536
    add  ebx,12                     ; + ширина кнопки
    mov  ecx,5*65536+12             ; [y start] *65536 + [y size]
    mov  edx,1                      ; идентификатор кнопки
    mov  esi,0x6688dd               ; цвет кнопки RRGGBB
    int  0x40

 ...

 ; Сюда записывается информация о процессе

 PInfo:
 processor_use:
         dd 0
 stack_pos:
         dw 0
 stack_value:
         dd 0
 process_name:
         db 0,0,0,0,0,0,0,0,0,0,0,0
 process_address:
         dd 0
 used_memory:
         dd 0
 process_id:
         dd 0
 process_x_coord:
         dd 0
 process_y_coord:
         dd 0
 process_window_width:
         dd 320
 process_window_height:
         dd 240

В итоге мы имеем приятное окошко с кнопочкой «close», всегда болтающейся в правом верхнем углу, как бы мы не меняли ширину окна. сорец в бонусе (coolapp.asm).

Теперь коснемся сети. В документации ясно и понятно сказано,что в стеке tcp/ip уже реализовано:

IP layer. ICMP. TCP layer. UDP layer. + готово: local loopback. Realtek 8029 PCI ethernet interface. Realtek 8139 PCI ethernet interface. Intel i8255x PCI ethernet interface. Dynamic ARP table. PPP dialer И пока в процессе: The IP layer process header options. The IP layer support routing. Packet fragmentation.

Взаимодействие машин в сети под управление MeOS, также как и на подавляющем большинстве других платформ, осуществляется с помощью всеми любимых сокетов.

В бонусе идут 2 файлика: client.asm/server.asm Сервер открывает сокет на 83-м порту:

    mov  eax,53            ; open tcp socket
    mov  ebx,5             ;
    mov  ecx,[local_port]  ; 83rd port
    mov  edx,0             ; remote port 0, because it's not necessary for us
    mov  esi,0             ; remote ip address also are not necessary
    mov  edi,0             ; mode: SOCKET_PASSIVE
    int  0x40

 , слушает и отображает приходящие данные:

    mov  eax,53            ; poll socket
    mov  ebx,2             
    mov  ecx,[socket]
    int  0x40              ;
    cmp  eax,0             ; in EAX - number of bytes in socket buffer
    je   no_data

    mov  eax,53            ; read data from socket
    mov  ebx,3
    mov  ecx,[socket]
    int  0x40              ; in BL after this - data byte
    mov  byte [text+ebp],bl

    <...>

И т.д (полный src в бонусе).

 

 

 

Клиент соответственно коннектится на порт и шлет данные, которые вводятся с клавы. Самое приятное, что можно пересылать данные хоть по одному байтику (что я и делаю в примере):

 key:                       ; key pressed
    mov  eax,2              ; just read it
    int  0x40
    cmp  al,0               ; al = 0 - key pressed
    jne  still              ; in AH - code of a key

    <...>

    mov  eax,53             ; write symbol to socket
    mov  ebx,7              ;
    mov  ecx,[socket]      
    mov  edx,1              ; bytes to write
    mov  esi,text           ; address to data
    add  esi,ebp
    int  0x40

Подводя итог этому краткому повествованию, можно сказать, что MeOS, конечно, ещё очень и очень далеко до уровня более-менее серьёзных операционных систем, но начало, как мне кажется очень даже неплохое.

references:

[1] http://www.menuetos.org

[2] http://www.flatassembler.net

[3] http://www.menuet.narod.ru

Что-то я засиделся с написанием статьи до поздна, а ведь завтра с утра на работу. Благо, у меня есть новый отличный матрас, купленный в анатомии сна. Оплата и доставка Анатомия Сна производится быстро, без проблем, доставка тоже очень быстрая, равно в оговоренные сроки.

 

 



©2013 Журнал Хакера Entries (RSS) and Comments (RSS)