_ _:. :$$$$$ _ . - +. :l$││$$ s┐┐,,_ +:@QSSS$$$$$ `` $$$$$$$$bs┐.`"┘?$$$l [ MeOs or ] '└└?$$│$$$$b┐_ . [ Another one "Toy story".. ] `"└$│$b. . [ Mr.Clumsy ] `└?b. `. [ clumsy@ngs.ru ] `┘. + `$ _. ` Изначально я планировал сделать более-менее подробный обзор этой операционной системы, но так как информации по ней более чем достаточно, то было решено ограничиться небольшим описанием. История этой операционки уходит корнями в далёкий 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