Как-никак, а развитие ядра потихоньку идёт.
В последнее время мною был реализован загрузчик PE-файлов в память с последующим запуском в user level. Реализация загрузчика PE немножко замедлила реализацию загрузчика файлов формата ELF, так как я обнаружил серьёзные изъяны в функциях, работающих с файлами. Нужно будет переписывать их реализацию. А так, надеюсь, к сентябрю успею выпустить новый релиз.
Posts Tagged ‘xsystem’
Развитие XSystem
Август 27th, 2009Менеджер виртуальной памяти
Июнь 26th, 2009Всё-таки нашёл в себе силы реализовать менеджер виртуальной памяти в XSystem. Конечно, готов он не на все 100%, но бОльшая часть уже действительно оттестирована и работает. Как подтверждение этого ядро было переведено на новый менеджер, а старый был выкинут из дерева проекта.
Теперь ядро умеет одинаково хорошо обращаться с обычной страничной адресацией и PAE (Page-Address Extension). Для этого достаточно перекомпилировать ядро с соответствующими параметрами.
В ближайшее время на wiki постараюсь разместить документацию по сделанному менеджеру. Зато сейчас как гора с плеч: пришлось очень долго и очень много думать, как правильнее реализовать менеджер. Теперь же можно потихоньку начинать разделять user-space и kernel-space для процессов.
Механизм подкачки пока не реализован, но это уже – отдельный разговор.
Inline assembly: GCC + Watcom.
Апрель 8th, 2009Задумался о кросс-компиляции моего ядрышка GCC (сейчас пока компилируется только Watcom’ом).
Первый большой и краеугольный камень – это, конечно, ассемблерные вставки. Поэтому был придуман механизм, чтобы минимизировать писанину и дублирование ассемблерного кода для обоих компиляторов. С этой целью я сделал некий заголовочный файл, в котором объявил:
Hand-made синхронизация репозиториев Subversion
Март 29th, 2009Несмотря на то, что репозиторий ОС XSystem мигрировал ко мне на домашний сервер, всё же хорошо было бы хранить бэкапы на каком-нибудь удалённом сервере.
Для этого я решил воспользоваться уже имеющимся репозиторием subversion на http://sourceforge.net/.
Идея работы такая: раз в сутки мой репозиторий должен синхронизироваться с удалённым репозиторием. При этом, все изменения в одном репозитории должны однозначно отражаться на другом. С версии subversion 1.4 появилась такая тулза, как svnsync, но она для моего случая не подходит: оба репозитория не предоставляют прямого доступа к svnroot.
В результате всё это было сведено к скрипту на PERL.
#!/usr/bin/perl
use strict;
my @blacklist =
(
qr(^\.svn|\/\.svn$),
qr(^\.{1,2}$|\/\.{1,2}$)
);
my $src_path = 'xsystem';
my $dst_path = 'xskernel-sync';
my $svn_user = '';
my $svn_pass = '';
# Update repositories
`svn update $src_path`;
`svn update $dst_path`;
# now search files in src_path and compare to dst_path
add_files();
remove_files();
`svn commit $dst_path -m "Synchronization commit" --username $svn_user --password $svn_pass`;
Как видно, работа скрипта достаточно примитивна. Для его работы нужно иметь два рабочих снимка репозитория: source и destination. У меня source-репозиторий находится в каталоге xsystem, а destination – в каталоге dst_path.
Скрипт сначала обновляет снимки репозиториев, затем осуществляет вливание новых файлов в destination-репозиторий при помощи функции add_files(). После этого удаляются устаревшие файлы и каталоги из destination-репозитория функцией remove_files() и производится коммит изменений в destination-репозиторий.
Дело осталось за малым – разобрать функции добавления и удаления файлов и каталогов. Для этого сначала напишем функцию, которая получает md5sum файла:
sub md5sum
{
my $fname = shift;
if (open PIPE, "md5sum $fname |")
{
my $line =
;
close PIPE;
my ($sum) = ($line =~ /^(\w+)\s+/o);
return $sum;
}
return undef;
}
В принципе, ничего нового. Вызывается утилита md5sum и анализируется её вывод.
Также необходимо игнорировать каталоги ".svn", "." и "..", для чего вводится массив @blacklist и пишется функция банинга файлов:
sub ban_file
{
my $src_file = shift;
foreach (@blacklist)
{
($src_file =~ $_) and
return 1;
}
return undef;
}
После этого можно спокойно разобрать функцию add_files():
sub add_files
{
my @directories = ();
my $curr_dir = '';
do
{
# Открываем каталог
if (opendir DIRHDL, "$src_path$curr_dir")
{
CYCLE: # Читаем содержимое каталога
while (my $fname = readdir DIRHDL)
{
# Баним ненужные файлы
my $src_file = "$src_path$curr_dir/$fname";
(ban_file($src_file)) and
next CYCLE;
my $dst_short = "$curr_dir/$fname";
my $dst_file = "$dst_path$dst_short";
# Файл является каталогом?
if (-d $src_file)
{
# необходимо проверить, что он есть в destination-репозитории
unless (-d $dst_file)
{
# если каталога нет - его нужно создать
print "mkdir $dst_short\n";
`mkdir -p $dst_file`;
`svn add $dst_file`;
}
# Запомним каталог для того, чтобы в будущем его просмотреть
push @directories, $dst_short;
}
else
{
# проверяем, существует ли файл в destination-репозитории
unless (-e $dst_file)
{
# файл не существует, его нужно скопировать и добавить
print "add $dst_short\n";
`cp -f $src_file $dst_file`;
`svn add $dst_file`;
}
else
{
# файл существует, вычисляем md5sum обоих файлов
my $sum1 = md5sum($src_file);
my $sum2 = md5sum($dst_file);
# если суммы не совпадают - заменяем файл новым
if ($sum1 ne $sum2)
{
print "replace $dst_short\n";
`cp -f $src_file $dst_file`;
}
}
}
}
}
else
{
print "Can't open dir $src_path$curr_dir\n";
}
# закрываем каталог и получаем следующий каталог, который следует обработать
closedir DIRHDL;
$curr_dir = shift @directories;
}
while (defined $curr_dir); # крутимся, пока в списке присутствуют обрабатываемые каталоги.
}
При удалении функция будет очень похожа, только теперь надо осуществлять поиск файлов в destination-репозитории и смотреть, есть ли они в source-репозитории:
sub remove_files
{
my @directories = ();
my $curr_dir = '';
do
{
# опять же, открываем каталог destination-репозитория
if (opendir DIRHDL, "$dst_path$curr_dir")
{
CYCLE: # читаем файлы
while (my $fname = readdir DIRHDL)
{
# баним недопустимые diren'ы
my $src_file = "$dst_path$curr_dir/$fname";
(ban_file($src_file))
and next CYCLE;
my $src_short = "$curr_dir/$fname";
my $dst_file = "$src_path$src_short";
# проверяем, является ли это каталогом
if (-d $src_file)
{
# проверяем, существует ли этот каталог в source-репозитории
unless (-d $dst_file)
{
# каталога нет - удаляем его из destination-репозитория
print "rmdir $src_short\n";
`svn delete $src_file`;
}
else
{
# каталог существует, запоминаем его для дальнейшей обработки
push @directories, $src_short;
}
}
else
{
# Это обычный файл, проверяем, есть ли он в source-репозитории
unless (-e $dst_file)
{
# Файла нет, удаляем его из destination-репозитория
print "unlink $src_short\n";
`svn delete $src_file`;
}
}
}
}
else
{
print "Can't open dir $dst_path$curr_dir\n";
}
# Закрываем каталог, получаем следующий
closedir DIRHDL;
$curr_dir = shift @directories;
}
while (defined $curr_dir);
}
Недостаток этой тулзы один: если файл был перемещён, то он будет распознан как новый файл. Хотя, я не думаю, что файлы и каталоги так часто перемещаются в логически корректно построенном дереве проекта.
Как я поднимал SVN
Март 29th, 2009Собственно, данный пост я решил написать после ночных бдений с SVN. Да, у меня были проблемы, которые пришлось решить, возможно, нестандартными методами, но зато теперь всё работает так, как я хотел.
Управление репозиторием
Итак, для всего этого нам нужнен сам Apache (я использовал Apache 2) и дополнительные модули: dav и dav_svn.
Помимо этого, я ещё поставил просматривалку репозитория ViewVC, с которой потом долго и провозился.
Для того, чтобы заставить работать subversion через http, достаточно сделать следующее (делал в OpenSUSE 10.3):
Сначала включаем модули при помощи a2enmod:
a2enmod dav a2enmod dav_svn
Теперь можно перезагрузить конфигу апача (либо через restart, либо через reload):
/etc/init.d/apache2 restart
или
/etc/init.d/apache2 reload
После этого необходимо сконфигурировать виртуальный хост. Лично я хотел, чтобы у меня SVN-репозиторий был как отдельный поддомен в домене xskernel.org – то есть, svn.xskernel.org.
Для этого заводим отдельный виртуальный хост в апаче:
<VirtualHost *:80>
ServerName svn.xskernel.org
ErrorLog /var/log/apache2/svn-error.log
TransferLog /var/log/apache2/svn-access.log
<Location /svn >
DAV svn
SVNPath /home/svn/repositories/svn.xskernel.org
SVNListParentPath on
AuthType Basic
AuthName "XSystem Kernel Team repository"
AuthBasicProvider file
AuthUserFile /home/svn/auth/svn.xskernel.org.htpasswd
SetOutputFilter DEFLATE
<LimitExcept GET PROPFIND OPTIONS REPORT>
Require valid-user
</LimitExcept>
</Location>
</VirtualHost>
Как видно, здесь в конфиге заводится локейшн /svn, который используется для работы DAV. Именно DAV позволяет полноценно работать с репозиторием через http.
Рассмотрим некоторые параметры:
SVNPath задаёт каталог, в котором располагается репозиторий, который будет ассоциирован с данным виртуальным хостом. Естественно, сам SVNRoot я спрятал (не стал использовать SVNRootPath).
AuthUserFile – файл, в котором будут в дальнейшем храниться пользователи и хэши их паролей, которым будет разрешён доступ в SVN.
LimitExcept накладывает ограничения на все команды кроме GET, PROPFIND, OPTIONS и REPORT, требуя авторизации (Require valid-user).
Отлично, теперь нужно завести соответствующий репозиторий. Я решил хранить все репозитории в отдельном каталоге /home/svn/repositories, поэтому создал репозиторий таким образом:
mkdir -p /home/svn/repositories svnadmin create /home/svn/repositories/svn.xskernel.org
Отлично, теперь репозиторий есть, надо сделать авторизацию. Для этого создаю файл паролей и завожу в нём пользователя:
mkdir -p /home/svn/auth touch /home/svn/auth/svn.xskernel.org.htpasswd htpasswd2 /home/svn/auth/svn.xskernel.org.htpasswd username
Теперь апачу нужно дать права на пользование репозиторием и файлами паролей, для чего присваиваю всем файлам пользователя, под которым работает апач:
chown -Rv webserver:web /home/svn
Сохраняем конфигурационный файл виртуальных хостов апача, перезагружаем конфигурацию по reload, и пробуем зайти по адресу http://svn.xskernel.org/svn/. WebDAV работает!
Просматривание репозитория
Вот с просматривалкой у меня и возникло много проблем. Хотелось, чтобы при заходе на http://svn.xskernel.org/ автоматически запускалась просматривалка, при этом она отображала бы только тот репозиторий, который ассоциирован с данным виртуальным хостом. Я перепробовал много различных вариантов и, в конце-концов, остановился на том, что изложу ниже.
WebDAV я поставил штатными средствами OpenSUSE – из репозитория, после чего забрал его из /srv/www и переместил в каталог /home/svn.
Для своего виртуального хоста завёл отдельную конфигу /home/svn/viewvc-svn.xskernel.org.conf, в которой прописал следующие параметры:
# Доступные репозитории для просмотра
svn_roots:
svn.xskernel.org : /home/svn/repositories/svn.xskernel.org
# Репозиторий, который следует просматривать по умолчанию
default_root = svn.xskernel.org
# Адрес обратной связи
address = team@xskernel.org
# Не использовать корень как компонент URL (то есть, не отображаются остальные репозитории в корне)
root_as_url_component = 0
# Путь к файлам с шаблонами отображения веб-страницы
template_dir = /home/svn/viewvc/svn.xskernel.org/templates
# компонент URL, по которому будут располагаться ресурсы для просматривалки (картинки и пр.)
docroot = /viewvc-docroot
Теперь заводим скрипт, который цепляет эту конфигу, копируя стандартный:
cp /home/svn/bin/cgi/viewvc.cgi /home/svn/bin/cgi/viewvc-svn.xskernel.org.cgi
И редактируем строки, прописывая:
LIBRARY_DIR = r"/home/svn/lib" CONF_PATHNAME = r"/home/svn/viewvc-svn.xskernel.org.conf"
Теперь скрипт /home/svn/bin/cgi/viewvc-svn.xskernel.org.cgi хватает конфигу /home/svn/viewvc-svn.xskernel.org.conf.
После всего этого заводим свои темплейты для ViewVC:
mkdir -p /home/svn/viewvc/svn.xskernel.org cp -R /home/svn/templates /home/svn/viewvc/svn.xskernel.org cp -R /home/svn/templates/docroot /home/svn/viewvc/svn.xskernel.org/viewvc-docroot
Прикручивание ViewVC к апачу
Теперь надо в каталоге /home/svn/viewvc/svn.xskernel.org завести файл index.html, который редиректит на подкаталог "/viewvc":
<pre> <html><head><META HTTP-EQUIV="Refresh" CONTENT="0; URL=/viewvc"><head> <body></body> </html> </pre>
Сделано это так потому, что если сам Апач осуществит редирект, SVN-клиент начнёт ругаться, что не может выполнить PROPFIND при импорте репозитория (проверено уже часовыми бдениями над mod_rewrie).
Прописываем ViewVC в конфиге виртуального хоста:
<VirtualHost *:80>
#...
ScriptAlias /viewvc "/home/svn/bin/cgi/viewvc-svn.xskernel.org.cgi"
Alias / /home/svn/viewvc/svn.xskernel.org/
<Directory /home/svn/viewvc/svn.xskernel.org/ >
Order allow,deny
Allow from all
DirectoryIndex index.html
</Directory>
</VirtualHost>
Параметр ScriptAlias указывает, какой скрипт следует запускать, когда URL содержит "/viewvc".
Перезагружаем конфигу апача, пробуем: http://svn.xskernel.org/.
Грузится страничка index.html, которая автоматом нас редиректит на http://svn.xskernel.org/viewvc/ и запускается скрипт /home/svn/bin/cgi/viewvc-svn.xskernel.org.cgi .
Заключение
Как видно, не всё так красиво в моей настройке, как хотелось бы. Если есть соображения/советы, как сделать лучше, то я их внимательно выслушаю.
Тем не менее, репозиторий ОС XSystem переехал с SourceForge.net ко мне на домашний сервер. Работает на порядок быстрее, чем тормозной сервис от SourceForge.net. Однако, от SF.net я не стал отказываться, а сделал его зеркалом моего репозитория. Как – в следующем посте.
Не все виртуалки превосходны.
Ноябрь 6th, 2008В связи с тем, что на форуме появился очень интересный баг:
http://forum.xskernel.org/viewtopic.php?f=10&t=18
Решил поиграться с виртуальными машинами, а именно проверить, как на них запускается XSystem.
Вот что из этого получилось:
А развитие идёт дальше…
Ноябрь 3rd, 2008Выпущен новый релиз ОС XSystem – October 2008 Fishes: Carp.
Основные нововведения:
- Из дерева проекта удалены утилиты ‘xarch’ и ‘fontcut’.
- Полностью переписан планировщик (теперь более быстрый и надёжный).
- Блочный распределитель памяти теперь выделяет блоки с адресом, кратным 8 байтам.
- Исправлены ошибки в контроллере клавиатуры (теперь работает в Bochs).
- Оптимизации реализации библиотеки <string.h>.
- Частично перенесён код Watcom C++ Runtime Library, необходимый для использования C++ – конструкций.
- Изменены сборочные скрипты.
- Кодовые страницы перемещены в ‘media/share/codepages’.
- Изменён метод ‘for_file’ в утилите ‘xsmake’.
- Большинство архитектурно-зависимого кода вынесено в ветку ‘include/arch’ ядра.
- Написан прототип будущего механизма подкачки виртуальной памяти.
- Добавлена поддержка записи конфигурационного пространства шины PCI (экспериментальное).
- Реализована поддержка загрузки/сохранения контекстов FPU/MMX/SSE при переключении задач.
- Добавлена защита от ошибочного прерывания со стороны PIC.
- Доступна загрузка с USB Flash Drive.
- Первичный загрузчик (’bootload’) полностью переписан для поддержки файловых систем FAT12 и FAT16.
- Вторичный загрузчик ‘xload’ переписан на C++.
- Добавлены функции ‘unlink’, ‘cp’ в утилите ‘xsmake’.
- Добавлена условная конструкция ‘if-else’ в утилиту ‘xsmake’.
- Добавлена проверка зависимостей в OMF-файлах утилитой ‘xsmake’.
- Переписана утилита ‘rawmake’ (поддержка создания образов FAT12 и FAT16-дисков).
- Утилиты ‘xsmake’, ‘exe2bin’ и ‘rawmake’ теперь также можно собрать с помощью GNU GCC под Linux.
Форум
Октябрь 15th, 2008Вот и дожили до того, что открыл форум своего проекта.
Расположен он здесь: http://forum.xskernel.org/
Если есть желание реально поучаствовать в проекте и/или обсудить его – приветствую гостей.
Основной сайт тут: http://xskernel.org/ .
А здесь можно найти кое-какую полезную документацию: http://wiki.xskernel.org/ .
Странно…
Октябрь 5th, 2008Уже где-то вторую или третью неделю непроизвольно соблюдаю правило «ни дня без коммита».
Хм… К чему бы это? Наверное, к новому релизу…
Написал статейку на WIKI про планировщик потоков:
http://wiki.xskernel.org/doku.php/xskernel/ipc/scheduler
Новый планировщик пофиксил много неприятных багов и корявостей в ядре. И (о чудо!), казалось бы, для более сложной реализации планировщика новая версия работает на порядок быстрее старой.
xskernel.org жив!
Август 30th, 2008Домен xskernel.org после долгого пребывания в небытии снова вернулся ко мне!
Ура ура ура!