3. Первые вздохи ядра (head.S)
Ядро к сожалению опять начнется с ассемблерного кода. Но теперь его будет совсем немного.
Мы собственно зададим правильные значения сегментов для данных (ES, DS, FS, GS). Записав туда значение соответствующего дескриптора данных.
cld
cli
movl $(__KERNEL_DS),%eax
movl %ax,%ds
movl %ax,%es
movl %ax,%fs
movl %ax,%gs
Проверим, нормально ли включилась адресная линия A20 простым тестом записи. Обнулим для чистоты эксперимента регистр флагов.
xorl %eax,%eax
1: incl %eax
movl %eax,0x000000
cmpl %eax,0x100000
je 1b
pushl $0
popfl
Вызовем долгожданную функцию, уже написанную на С.
call SYMBOL_NAME(start_my_kernel)
И больше нам тут делать нечего.
inf: jmp inf
4. Поговорим на языке высокого уровня (start.c)Вот теперь мы вернулись к тому с чего начинали рассказ. Почти вернулись, потому что printf() теперь надо делать вручную. поскольку готовых прерываний уже нет, то будем использовать прямую запись в видеопамять. Для любопытных - почти весь код этой части , с незначительными изменениями, повзаимствован из части ядра Linux, осуществляющей распаковку (/arch/i386/boot/compressed/*). Для сборки вам потребуется дополнительно определить такие макросы как inb(), outb(), inb_p(), outb_p(). Готовые определения проще всего одолжить из любой версии Linux.
Теперь, дабы не путаться со встроенными в glibc функциями, отменим их определение
#undef memcpy
Зададим несколько своих
static void puts(const char *);
static char *vidmem = (char *)0xb8000; /*адрес видеопамати*/
static int vidport; /*видеопорт*/
static int lines, cols; /*количество линий и строк на экран*/
static int curr_x,curr_y; /*текущее положение курсора */
И начнем, наконец, писать код на языке высокого уровня... правда с небольшими ассемблерными вставками.
/*функция перевода курсора в положение (x,y). Работа ведется через ввод/вывод в видеопорт*/
void gotoxy(int x, int y)
{
int pos;
pos = (x + cols * y) * 2;
outb_p(14, vidport);
outb_p(0xff & (pos >> 9), vidport+1);
outb_p(15, vidport);
outb_p(0xff & (pos >> 1), vidport+1);
}
/*функция прокручивания экрана. Работает, используя прямую запись в видеопамять*/
static void scroll()
{
int i;
memcpy ( vidmem, vidmem + cols * 2, ( lines - 1 ) * cols * 2 );
for ( i = ( lines - 1 ) * cols * 2; i < lines * cols * 2; i += 2 )
vidmem[i] = ' ';
}
/*функция вывода строки на экран*/
static void puts(const char *s)
{
int x,y;
char c;
x = curr_x;
y = curr_y;
while ( ( c = *s++ ) != '' ) {
if ( c == 'n' ) {
x = 0;
if ( ++y >= lines ) {
scroll();
y--;
}
} else {
vidmem [ ( x + cols * y ) * 2 ] = c;
if ( ++x >= cols ) {
x = 0;
if ( ++y >= lines ) {
scroll();
y--;
}
}
}
}
gotoxy(x,y);
}
/*функция копирования из одной области памяти в другую. Заместитель стандартной функции glibc */
void* memcpy(void* __dest, __const void* __src,
unsigned int __n)
{
int i;
char *d = (char *)__dest, *s = (char *)__src;
for (i=0;i<__n;i++) d[i] = s[i];
}
/*функция издающая долгий и протяжных звук. Использует только ввод/вывод в порты поэтому очень полезна для отладки*/
make_sound()
{
__asm__("
movb $0xB6, %alnt
outb %al, $0x43nt
movb $0x0D, %alnt
outb %al, $0x42nt
movb $0x11, %alnt
outb %al, $0x42nt
inb $0x61, %alnt
orb $3, %alnt
outb %al, $0x61nt
");
}
/*А вот и основная функция*/
int start_my_kernel()
{
/*задаются основные параметры */
vidmem = (char *) 0xb8000;
vidport = 0x3d4;
lines = 25;
cols = 80;
/*считывается предусмотрительно сохраненные координаты курсора*/
curr_x=*(unsigned char *)(0x8000);
curr_y=*(unsigned char *)(0x8001);
/*выводится строка*/
puts("donen");
/*уходим в бесконечный цикл*/
while(1);
}
Вот и вывели мы этот "Hello World" на экран. Сколько проделано работы, а на экране только две строчки
Booting data ...done
Go to proteсted mode ...done
Немного, но и немало. Закричала новая операционная система. Мир с радостью воспринял ее. Кто знает, может быть это новый Linux ...
5. Подготовка загрузочного образа (floppy.img)
Итак, подготовим загрузочный образ нашей системки.
Для начала соберем загрузочный сектор.
as86 -0 -a -o boot.o boot.S
ld86 -0 -s -o boot.img boot.o
Обрежем 32 битный заголовок и получим таким образом чистый двоичный код.
dd if=boot.img of=boot.bin bs=32 skip=1
Соберем ядро
gcc -traditional -c head.S -o head.o
gcc -O2 -DSTDC_HEADERS -c start.c
При компоновке НЕ ЗАБУДБЬТЕ параметр "-T" он указывает относительно которого смещения вести расчеты, в нашем случае поскольку ядро грузится по адресy 0x1000, то и смещение соотетствующее
ld -m elf_i386 -Ttext 0x1000 -e startup_32 head.o start.o -o head.img
Очистим зерна от плевел, то есть чистый двоичный код от всеческих служебных заголовков и комментариев
objcopy -O binary -R .note -R .comment -S head.img head.bin
И соединяем воедино загрузочный сектор и ядро
cat boot.bin head.bin >floppy.img
Образ готов. Записываем на дискетку (заготовьте несколько для экспериментов, я прикончил три штуки) перезагружаем компьютер и наслаждаемся.
cat floppy.img >/dev/fd0
6. Е-мое, что ж я сделал (...)
Здорово, правда? Приятно почувствовать себя будущим Торвальдсом или кем-то еще. Красная линия намечена, можно смело идти вперед, дописывать и переписывать систему. Описанная процедура пока что едина для множества операционных систем, будь то UNIX или Windows. Что напишете Вы? ... не знает не кто. Ведь это будет Ваша сист
... of job. Because I suppose if than marriage he must provide his family. And the young coups must that they meant for understand each other. Customs and holidays in English – speaking countries. - Customs and holidays in the urban community are of great importance for everyone. - I think no matter who the man might be he must know customs and holidays his country. What holidays do you ...
... программе. В данном разделе они перечислены в алфавитном порядке и приводятся с объяснениями. Эти ошибки могут являться следствием случайного затирание памяти программой. Abnormal program termination Аварийное завершение программы Данное сообщение может появляться, если для выполнения программы не может быть выделено достаточного количества памяти. Более подробно оно рассматривается в конце ...
... новую песню?) Yes, I will (да, приду, да, буду, да сделаю). Не то чтобы will сдавал позиции. Просто come и gonna отвоевывают позиции под лучами англоязычного солнца. Конечно, об активном разговорном American English — языке общаг, кухонь, "Макдональдсов", спортивных площадок, колледжей и казарм — можно говорить еще и еще, но, как выражаются американцы: next time — как-нибудь в следующий раз. ...
... озвончения в середине слова после безударного гласного в словах французского происхождения. Зав. кафедрой -------------------------------------------------- Экзаменационный билет по предмету ИСТОРИЯ АНГЛИЙСКОГО ЯЗЫКА И ВВЕДЕНИЕ В СПЕЦФИЛОЛОГИЮ Билет № 12 Дайте лингвистическую характеристику "Младшей Эдды". Проанализируйте общественные условия национальной жизни Англии, ...
0 комментариев