اهلا وسهلا بالشباب
ناتى الان معنا الى الدرس الثالث الممتع من دورتنا الخاصة بتصميم انظمة التشغيل
وبعد ما انتيهنا من برمجة boot.s وloader
سوف نتكلم عن اليوم عن جزء اخر وهو الخاص بلغة c الشهيرة
(START.C)
ولكن لسوء الحظ النواة يجب ان تبدأ بالاسمبلر وبالرغم من ذلك فلن نحتاج اليها كثيرا
ينبغى علينا تعريف القيم والمتغيرات الصحيحة للبيانات فقط (es, ds, fs, gs)
وحفظها الى جدول بيانات المواصفات
cld cli movl $(___KERNEL_DS),%eax movl %ax,%ds movl %ax,%es movl %ax,%fs movl %ax,%gs
الان علينا فحص ما اذا كان العنوان A20 قد تم فتحه بطريقة صحيحة بوسيلة كتابة بسيطة
من اجل التجربة لتكون صحيحة علينا جعل flags صفرا
xorl %eax,%eax 1: incl %eax mov %eax,0x000000 cmpl %eax,0x100000 je 1b pushl $0 popfl
الان سنستدعى الفنشكن المكتوبة بلغة الC
call SYMBOL_NAME (start_my_kernel)
وهى كذلك
inf: jmp inf
الان تقريبا نحن رجعنا الى ما بدانا اليه فى البداية لاننا نحتاج الى عمل "Printf" بأيدينا لانه ليس هناك مقاطعات
فى الوضع المحمى بل بورتات فقط نحن سوف نكتب مباشرة الى Video Memory
وطبعا لاننى لست عالم كمبيوتر فانا مجرد فتى من مصر عمره 15 سنة
فسوف استعير هذا الكود من نظام اقلاع لينكس (arch/i386/boot/compressed)
بدون اى تعديلات عليه لاستخدام الاسمبلى الذى نريد
الماكرو الاتى inb(), outb(), inb_p(), out_p()
انظر الى لينكس الان هذا الفنكشن تم بناءه باستخدام glibc لذا سنقوم بالكنسلة عليه
#undef memcpy memcpy
سنقوم بتعريف الفنكشنات الخاصة بنا
static void puts(const char *); static char vidmem =(char)0xb8000; /*video memory address*/ static int vidport; /*videoport*/ static int lines,cols; /* number of lines and colors on a screen*/ static int curr_x,curr_y; /*current cursor position*/
والان سنقوم ببدء البرنامج فى وضع (High-Level) بالاضافة الى assembly بالطبع
الدالة ov تقوم بنقل cursor الى (x,y).
وهذا يحدث باستخدام I/O فى بورت الفيديو
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);
}
Screen scrolling function. Works using direct writing into video memory.
static void puts(const char*s)
{
int x,y;
char c;
x=curr_x;
y=curr_y
while((c=*s++)!=``){
if(c==``){
x=0;
f(++y>=lines){
scroll();
y--;
}
}
else{
vidmem[(x+cols*y)*2]=c;
if(++x>=cols){
x=0;
if(++y>=lines){
scroll();
y--;
}
}
}
}
gotoxy(x,y);
}
Function copy from one part of memory to another.
Void* memcpy( void*__dest,__const void*___src,unsigned int__n)
{
int I;
char*d=(char*)dest,*s=(char*)__src;
for(I=o;I<__n,I++) d =s
}
Function, making long nice. Very usefull for debugging.
Make_sound()
{
__asm__("
movb $0xB6, %al
outb %al,$0x43
movb $0x0D, %al
outb %al,$0x43
movb $0x11,%al
outb %al,$0x42
inb $0x61,%al
orb $3,%al
outb %al,
outb %al,$0x61
");
}
And here is the main function.
Int start_my_kernel()
{
/*setting general parameters*/
vidmem=(char*)0xb8000;
vidport=0x3b4;
lines=25;
cots=80;
/* reading the saved cursor coordinates*/
curr_x=*(unsigned char *)(0x8000);
curr_y=*(unsigned char *)(0x80001);
/*show the following*/
puts("MiniOS Loaded/n");
/*Go into endless loop*/
while(1);
}الان هذه هى النهاية لدورتنا دورة سريعة اليست كذلك
لكن هذه ليست النهاية معنا فهذه نهاية الدورة المستوى الاول (Mini-Course )
والى اللقاء فى المستوى القادم المتوسط باذن الله
