В качестве информации: в SDCC любое предупреждение можно отключить.
--disable-warning <nnnn> Disable specific warning with number <nnnn>
Короче, захотел я собрать..
SDCC : mcs51/z80/z180/r2k/r3ka/gbz80/tlcs90/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8 3.4.1 #9108 (Nov 16 2014) (Linux)
А оно как сругается!
Как жить с этим?! Как побороть?Цитата:
sdcc -c --std-sdcc99 --no-std-crt0 -mz80 -I/home/salex/work-zx/FUZIX/Kernel/cpu-z80 -I/home/salex/work-zx/FUZIX/Kernel/platform-zx128 -I/home/salex/work-zx/FUZIX/Kernel/include --max-allocs-per-node 30000 --opt-code-size --Werror --stack-auto --constseg CONST --codeseg CODE2 syscall_proc.c
Internal error: validateLink failed in SPEC_NOUN(type) @ SDCCcse.c:1667: expected SPECIFIER, got DECLARATOR
Makefile:125: ошибка выполнения рецепта для цели <<syscall_proc.rel>>
make: *** [syscall_proc.rel] Ошибка 1
Хочу в итоге на Пентеве FUZIX. При её 4Мб можно не ограничиваться 5 задачами) даже есть по 16 кб на задачу - то 128 влезет)
К примеру взять релиз а не ночную сборку
Именно
https://github.com/EtchedPixels/FUZIX/issues/10
---------- Post added at 02:09 ---------- Previous post was at 02:03 ----------
На пентеве же крутой банкинг, как я понимаю, можно в любую банку включать что угодно. Поэтому под задачу можно исхитриться выделить 60 с лишним килобайт - всю память за вычетом лишь udata, стека и таблицы рестартов и прерываний.
Банкинг, конечно "крутой" в том смысле, что "любая страница в любое окно".
Но окна - всёж по 16К. Потому, чтобы избежать копирования - лучше 16/32/48К на задачу.
попробую релиз SDCC 3.4.0-rc3
В принципе - задача-минимум сделать загрузчик для Pentevo и менеджер памяти для неё же. Пока, для совместимости с 128мым пусть одно приложение будет не более 16 К.
Вдруг получится:)
Скомпилировать получилось.
Создал отдельную платформу для zxpentevo.
Что плохо - пути к библиотекам SDCC прибыты гвоздями. Прилагаю скрипт, который умеет спрашивать у SDCC пути к инклюдам и либам и выводить их в поток стандартного вывода.
Вечером, я надеюсь, буду пробовать запилить на живой пентеве загрузчик.
Запуши лучше Алану. Надо пользоваться тем, что у проекта есть живой мейнтейнер.
Или хотя бы в комменты к http://github.com/EtchedPixels/FUZIX/pull/4
Хотя один фиг для этого тоже надо на гитхабе регаться :)
---------- Post added at 12:56 ---------- Previous post was at 12:52 ----------
Всё копирование будет сводиться к переброске 256 байт udata. Счас все платформы через такой LDIR и работают.
Хотя я не знаю, как на пентеве переключается экран. Если он "прибит" к текущей банке в #4000, то его тоже надо копировать, а это уже да, не круто.
Идеальный вариант, наверное - это переключить экран на #C000 (если возможно в ATM-режиме) и щелкать только нижними тремя страницами. Тогда копирование сведется к однократному копированию таблицы векторов при старте нового процесса.
Прошу прощенья за пионерские вопросы - где в исходниках описываются аппаратные диспетчеры памяти? Осмотр "по диагонали" выявил только какие-то абстракции на тему простейшего управления памятью страничками по 4к. Как-то всё неочевидно, покрайней мере для непрограммиста - не просматривается прямая корреляция между аппаратными диспетчерами и дефайнами, которые там Алан сочинил и типа описал.
Вай-вай, дорогой, - зачем какой-то "лдир-шмир", когда есть ПДП 143кб/фрейм.
:)
На пентеве можно юзать расширенную графику, доступ к которой можно организовать через любое окно CPU, или блоками пересылать туда из основной памяти с помощью ПДП.
Те диспетчеры, которые bank16, bankfixed - они занимаются только выделением свободной страницы создаваемому процессу. И даже не самой страницы, а её номера. Тупо отслеживают, что занято, а что нет, больше ничего не делают.
А код, переключающий задачи (=переключающий страницы) платформно-специфичен и вынесены в ассемблерные файлы.
Это, по-сути, пять функций:
switchout - выполняется после того, как у процесса отбирается процессорное время.
swithin - выполняется перед тем как процессу выдается процессорное время
map_kernel - вернуть маппинг ядра
map_process - подключить страницы, занятые указанным процессом
do_fork - создать копию текущего процесса
От их реализации и зависит всё поведение системы.
---------- Post added at 17:02 ---------- Previous post was at 16:59 ----------
Ну тогда дело за малым.
Я потерялся в поиске примера где в коде Алана используется архитектура вот с этой картинки:
Код:First 64k Subsequent 64k banks
FFFF +------------+ +------------+
Common | Common | | Task Store |+
F000 +------------+ +------------+|+
| | | |+|+
| Kernel | | Process ||+|
Banked | Code | | Code |||+
| | | & Data ||||
| | | ||||
0100 +------------+ +------------+|||
| Reserved | | Reserved |+||
0000 +------------+ +------------+|+|
+------------+|+
+------------+|
Т.е. именно как оно (в каких функциях) использует диспетчер по 64к (он же 60к) для доступа к данным в другие страницы. В моем представлении это должны бы быть какие-то ассемблерные вставки, чтоли...
C этим более-менее понятно. Аналогично было и на UZIX, только функции по-другому назывались. Для UZIX эти модули я вчерне уже начинал писать, тогда не хватило упорства победить компилятор (это самая засада в программировании для Z80 на C).
Попробую.
---------- Post added at 12:56 ---------- Previous post was at 12:52 ----------
Если я начну всё и сразу делать - то точно нифуя не получится.
Сначала - загрузчик. Как загрузчик заработает и на консоль будет пукать, что ОС загрузилась - можно о чёмто другом говорить.
Наполеоновские планы обычно кончаются маниловскими делами...
Не, это не менеджер памяти в таком понимании. В fuzix каждый процесс фиксирован и за пределы 64к выходить не может - соответственно, никакого доступа к данным в других страницах нет.
Единственное исключение - вызов функций ядра через RST 30H (syscall). В этом случае процесс обращается к ядру, которое может быть расположено в других банках памяти. Это специфический случай и ради него те пять функций и сделаны.
---------- Post added at 17:40 ---------- Previous post was at 17:34 ----------
Естественно. К тому же драйвер ВГ93 и для zx128 пригодится. У меня счас упрощенный вариант, работающий через хаки эмулятора. Бьюсь над тем, чтобы заставить грузиться init.
что такое за команды out (21) ?
вроде такого порта в 128 спеке нет?
---------- Post added at 22:44 ---------- Previous post was at 22:40 ----------
Насколько я помню - в спеке 128 память так распределена:
Окно 0 - ПЗУ
Окно 1 - стр 5
ОКНО 2 - стр 2
Окно 3 - СТР 0..7
Где в ядре указано, что стр. 5 и 2 - заняты под ядро? В каком файле?
Если ты про lowlevel-z80, то это Алан сегодня какую-то отладочную хрень закоммитил. #21 и #1 - это порты маппера и терминала на z80pack, но не помню, какой чей :)
А если про zx128, то там все эти команды или закомментированы, или в начале функции ret стоит.
В zx128? Я там маппинг ещё не дописал. А так это должно быть в функции pagemap_init. Для страниц 2 и 5 не должна вызываться pagemap_add.Цитата:
Где в ядре указано, что стр. 5 и 2 - заняты под ядро? В каком файле?
Да там немногое изменилось-то :)
http://dl.dropboxusercontent.com/u/2...zx/fuzux_2.png
Ещё чуток вопросов.
1. У тебя в комментах написано, что ты снёс вё ядро ниже 0xC000. Что для 128К и нужно. Common at 0xf000 (2492 bytes) - это выше 0xC000. Так и надо?Цитата:
sdldz80 -n -k /usr/share/sdcc/lib/z80 -k /home/salex/apps-zx/sdcc/bin/../share/sdcc/lib/z80 -k /home/salex/apps-zx/sdcc/share/sdcc/lib/z80 -f platform-zx128/uzi.lnk
tools/analysemap <uzi.map
Code1: 15764 bytes
Code2: 16081 bytes
Code: 31845 bytes
Data: 2992 bytes
BSS: 0 bytes
Initialized: 5387 bytes
Free memory begins at: c817
Common is at: f000
Space: 10217 bytes
Work room: 4830 bytes
cp hogs.txt hogs.txt.old
tools/memhogs <uzi.map |sort -nr >hogs.txt
head -5 hogs.txt
7611: _memcpy
1663: __execve
1062: _writei
996: _readi
951: _tty_inproc
makebin -s 65536 -p uzi.ihx >uzi.tmp
tools/binman uzi.tmp uzi.map fuzix.bin
Code at 0x0000 (15764 bytes)
Code2 at 0x5b00 (16081 bytes)
Const at 0xa142 (538 bytes)
Data at 0xa75c (8379 bytes)
Common at 0xf000 (2492 bytes)
Font at 0xa35c (1024 bytes)
Video at 0x99d1 (1024 bytes)
Discard at 0x9dd1 (881 bytes)
End at 0xfdbc
2. Какая страница должна быть впечатана в окно 4 при инициализации ядра?
3. Задача загрузчика - просто включить RAM в 0x0000 - 0xFFFF, поместить бинарь с адреса 0x0000 и сделать jp 0x0000 ? Или через регистры какието параметры ядру передаются?
Eltaron, ты не закоммитил platform-zx128/devfd.h
без него ветка мастер не компилится.
У тебя свой репозиторий на https://github.com/atsidaev, как я понимаю?
Может создадим там же отдельную ветку для пентевы, а ты в мастер будешь сливать по своему усмотрению?
Я уже прикинул, что надо отделять конфиг от мэйкфайла. плюс скрипты и platform-zxpentevo.
Не, чуть не так.
Ядро занимает всё пространство 0000-FFFF за вычетом экрана. При создании нового процесса, ему выделяется очередная страница верхней памяти, которая подключается в C000 (заменяя собой страницу ядра), туда кладется бинарник процесса и запускается. Никаких проблем из-за того, что кусок ядра недоступен нет, потому что все вызовы ядра процесс выполняет через RST 30. Первое, что делает RST 30 - это возвращает в C000 страницу ядра. Потом он отрабатывает вызов, возвращает страницу процесса обратно и передает управление обратно процессу.
Common - это кусок памяти, общий для всех процессов и ядра. В z80pack это верхние 4 килобайта. Они не меняются при переключении банок, отсюда и название. У нас же наоборот, не меняются данные ниже C000, поэтому common нужно опускать туда. В своей ветке я это уже начал, но для полноценной отладки надо сначала научиться запускать процессы.
Нулевая. 0 - страница ядра, 5,2 - страницы нижней RAM. Для процессов остаются 1, 3, 4, 6, 7.Цитата:
2. Какая страница должна быть впечатана в окно 4 при инициализации ядра?
Да.Цитата:
3. Задача загрузчика - просто включить RAM в 0x0000 - 0xFFFF, поместить бинарь с адреса 0x0000 и сделать jp 0x0000 ?
Как-то можно передавать, но я это ещё не копал. Можно передать устройство загрузки, например, чтобы не вводить каждый раз его с клавы.Цитата:
Или через регистры какието параметры ядру передаются?
---------- Post added at 14:03 ---------- Previous post was at 13:54 ----------
Закоммитил файлик. Но от моего репозитория без моего хаканного эмулятора толку мало - там всё через этакий наколеночный DMA работает. Просто хочу сначала отладить переключение процессов, а загрузчиками и дровами заниматься потом.
Я могу создать ветку, но ты не сможешь в неё коммитить. Гитхаб не так работает. Тут все коммиты в чужие репозитории осуществляются как pull request'ы. Это когда форкаешь чужое репо, коммитишь в него изменения, а потом создаешь pull request - просьбу свои изменения включить в основной репозиторий. Можешь меня форкнуть, можешь сразу Кокса.Цитата:
Может создадим там же отдельную ветку для пентевы, а ты в мастер будешь сливать по своему усмотрению?
Я уже прикинул, что надо отделять конфиг от мэйкфайла. плюс скрипты и platform-zxpentevo.
Спасибо.
Я с гитхабом не работал. Зарегистрировался - буду разбираться по мере.
Как сделаю, что на пентеве в режиме 128 запустится ядро - так и форкну:)
Сейчас пилю загрузку по RS232. На скорости 115200 - это всего 5 сек и не надо с флешкой морочится. Для отладки удобно.
Если для Пентевы делать - тогда раскладку памяти другую надо:
Не нужна эта "дырка" в 6,75кб под спектрумовский экран. Нужно обеспечить "безболезненное" включение в какое-нибудь окно страниц экранной области, чтобы процесс мог туда быстро напрямую писать/читать.
Как вариант, в верхней памяти зарезервировать фиксированное место для размещения подпрограмм "рисования", тогда они могут, хоть все 3 остальных окна использовать. Либо автор программы на этапе сборки определит сколько и с какого адреса ему нужна память в 3-м окне.
Можно даже свободно пользоваться TR-DOS при необходимости.
Тока это не юникс уже будет. В Юниксе для записи в экранную область процессы используют функцию putchar/putc. :) И даже через либы они туда не пишут напрямую, а все заруливается через ядро.
Задачка на воображение: два процесса выполняются и оба параллельно лезут в экран. Что будет на экране? Даже не беря во внимание что все это происходит по прерыванию (и они переписывают порт считать который нельзя, т.е. состояние порта будет не детерменировано).
Слой абстракции в графике - это лишнее. И так всё еле ползать будет :)
Нам нужно что-то вроде фреймбуффера, куда пишут как раз напрямую. Даже фреймбуффер слишком сложно. Нам тупо нужен мьютекс, захватив который, процесс получает эксклюзивное право писать в экран.
Но т.к. мьютексов в фузихе ещё нету, то о графике думать вообще рано :)
Запустилось на реальной пентеве!
Карту памяти такую сварганил:
win0 - page7
win1 - page5
win2 - page2
win3 - page0
---------- Post added at 23:27 ---------- Previous post was at 23:25 ----------
Да нет. Я за поддержку реальной флеши и трдос-образин.
Просто для отладки, чтобы флешку не дрюкать - сварганил простеннькую прогу.
ну теперь можно дальше мучать!
---------- Post added at 23:29 ---------- Previous post was at 23:27 ----------
Юниксоиды, млин... Да можно в юниксе напрямую с видеопамятью работать. фреймбуфер мемапнул - и привет. Пиши как хочешь.
Если, конечно, права имеешь)
Не пишите "как хочешь", пишите как принято. :)
Может это и не очевидно, но написанное "как хочешь" потом все одно придется переделывать, собственно это и зацепило напоспорить. Если хочется графики, можно использовать, например, ncurses для ASCII, VNC для графики, и даже мапить память чтобы туда писать, но не каждым процессом как попало. И то и то уже реализовывалось для Z80, надо только руки приложить и портировать когда движок заработает. Что-то массово и быстро выводить на экран в графике нужно только играм, а там прослойка UZIX вообще ни к чему, лоадеры (буты\трдосы и и т.п.) уже написаны.
---------- Post added at 00:53 ---------- Previous post was at 00:47 ----------
На "больших" объемах, приближающихся к 32М ядро _очень_ медленно работает, заметно подтормаживают даже РС-версии fsck, mkfs, ucp. Кокс, кстати, писал об этом в блоге. Да и всего "богатства" бинарей в UZIX наработано на 4-5 Mb (а в Fuzix пока хорошо если 10% от этого). Тут надо смотреть на доработку ядра для во-первых модульно подключаемых библиотек сторонних ФС, и во-вторых к первому - имплементировании такого модуля для портированной FatFS. Вот на ней то и хранить любые объемы, работает по скорости приемлимо, проверял. А ФС типа "uzi" оставить только для rootfs.
---------- Post added at 00:58 ---------- Previous post was at 00:53 ----------
Мне в этом свете не понятно зачем в TODO у Алана числится допиливание ФС uzi до 32битных inod-ов, учитывая что обрабатывать long-и ядро будет еще в пару раз медленнее.
Ура, смог загрузить init. Ну, не настоящий init, а пример /Applications/ASM/init.s. Но процессы создаются и смена банок ядро<->процесс вроде бы отрабатывает корректно.
Образ дискеты (init + /dev/tty0) в аттаче на всякий случай.
Ну, это ж наши трехмегагерцовые проблемы. А для T80 падение скорости будет не очень заметно.
Я подумал - наверное и вправду на первых порах впилю виртуальный диск по RS232.
там функций то всего две - запись блока, чтение блока.
1. Какая ФС используется в FUZIX?
2. Какими утилитами можно создать образ этой ФС и записать на неё файлы?
Я думал, что тот образ, что ты приложил - UZIXовый, но UZIXовые утилиты его не поняли.
Предлагаю образ FUSIX хранить на TRDOS-дискете с 01 дорожки. 0-я дорожка стандартная, и пусть содержит единственный файл "boot" с загрузчиком. Так для эмулей, да и для реала удобней будет.
Если знать формат, думаю смогу на REXX написать. :)
Кстати, неплохо было бы ассемблерные файлы просмотреть на предмет оптимизации - можно больше места под процессы выделить
Это не проблема.
именно тип ФС я и спрашивал.
ИМХО, Раз Eltaron создал образ - то он знает тип ФС и у него есть утилиты..
Там под процесс выделяется окно 16К. Оптимизация нужна скорее по скорости.
В принципе, на пентеве можно и 48 К на процесс выделять - три окна по 16К.
теоретически - ОС занимает 48К (три окна). Под процессы остаются 253 окна по 16 К.
То есть - или имеем 253 процеса по 16 К или 84 процесса по 48К.
И то и другое - более чем достаточно для сепктрума.
Да, от TR-DOS там только структура 256x16x80x2.
ФС на неё хорошо ложится, одно надо учесть - в TR-DOS сектора в 256 байт, а в fuzix блок - 512 байт. Поэтому на каждый блок нужно читать два сектора.
Сама ФС fuzix-овая стандартная. Она же UZIX-овая стандартная и (судя по словам Error404) UZI-ховая стандартная.
Тулзы для её создания лежат в /Standalone, собираются под хост.
Создание файловой системы под стандартную TR-DOSную разметку:
init.s компиляется zmac. Я там у себя поменял tty1 на tty0 зачем-то, поэтому и создавать пришлось нод /dev/tty0.Код:./mkfs fuzix.trd 64 1280
./ucp fuzix.trd
> get init
> chmod 777 init
> mknod /dev/tty0 20666 257
> exit
Моё видение из разряда пожеланий:
1. Модульные драйверы, которые можно грузить по любому адресу и которые занимают переключаемые страницы.
2. Реализация драйвера работы с FLESHкой. (тупо флеш делить на N образов по 32Мбайта для начала можно).
3. Реализация драйвера RAM-диска динамического объёма.
Но пока это мечты...
---------- Post added at 16:23 ---------- Previous post was at 16:19 ----------
Тогда почему утилиты с сайта UZIX-утилиты http://prdownloads.sourceforge.net/f...ar.gz?download её не понимают?[COLOR="Silver"]
Без понятия. Собери свои, они в один make собираются.
Нет, все эти bank*.c - это файлы операционки, их желательно не трогать. Вся работа в platform-*.Цитата:
Eltaron, пожалуйста, ткни меня носом, где я могу прописать, какие именно старницы памяти используются ядром.
Чтобы менеджер памяти их не пытался использовать.
Это в bank16.c или нет?
Вообще, bank16.c - это для архитектур, у которых 4 банки по 16 килобайт, и в которых любую страницу можно включать в любое окно. Поскольку банкомат именно так и работает, то со временем ты на bank16 код и переделаешь.
Но пока что используется bankfixed.c. Это архитектура, в которой процесс лежит весь полностью в одной банке, но размер самой банки не оговаривается. 16 кб, 60 кб - не важно, главное, что один процесс - одна страница. (Есть одно НО - предполагается, что банка включается с адреса 0. Я поправил для zx128, но Алан этот коммит не взял, т.к. ломает прочие архитектуры. Значит, придется делать свой банкинг в platform-zx128.)
Так вот, тыкаю носом:
Если посмотришь все эти bank*.c, увидишь, что они реализуют набор одних и тех же функций. pagemap_add, pagemap_free, pagemap_alloc, pagemap_realloc. Указание менеджеру памяти на то, какие страницы есть - это pagemap_add. Она вызывается из pagemap_init в platform-zx128/main.c. У меня сейчас, к примеру, задаются только две свободные банки - 1 и 3 (ссылка на код)
Да я уже разобрался, спасибо.
По-хорошему твой коммит нужен в основной ветке. Не все ж ахитектуры именно с адреса 0 банки переключают.
Для z80, кстати нелогично с 0 банку включать. Там же рядом вектора лежат.
Может просто в конфиге ядра какой символ предусмотреть? Если он не определён - компилить как раньше. Если определёно - то как в твоём коммите.
ничего не поломается, зато всё в одной ветке.