الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

نحو بناء نظام تشغيل عربي

رائج
بدأه szerf في 19 يونيو 2008 · 156 رد · 42,832 مشاهدة · في هندسة البرمجيات
مشاركة: واتساب X فيسبوك تيليجرام
#101

بسم الله الرحمن الرحيم

حسنناً بالنسبه لطريقه التي اريدها هي المشاكل تعرض عن طريق برنامج المحادثه والدرس يوضع في المنتدي ويكون توقيت برنامج المحادثه 9:00 بتوقيت جرينتش تقريباً

*****************بالنسبه لطلب إعاده شرح جدول ال Gdt حسننأ انظر اسفل*********************

في البدايه ماهو النمط المحمي:

النمط المحمي نمط تعدد في اقسمام الذاكره كما حددها مبرمج النظام كل قسم يمتلك درجه حمايه مختلفه عن الأخر فقسم النظام له اعلي درجه حمايه حيث لا يستطيع اي برنامج يعمل التعدي في بيانات النظام من هنا اتت كلمه النمط المحمي حيث يتم حمايه نظام التشغيل الموجود في الذاكره ويتم حمايته بعد تحديد النظام للمعالج اي قسم هوه موجود فيه ويتم الولوج(اي جلب البيانات او تنفيذ شفره) عن طريق النظام الأتي محدد القسم:مكان البيانات او الشفره هذا خلاف النمط الحقيقي الذي يجلب البيانات عن طريق الشكل الأتي القسم:البيانات او الشفره .

ما متطلبت المرور إلي هذا النمط:

لكي يتم المرور إلي هذا النمط لابد من توافر شرطين 1-جدول التقسم او جدول المداخل او جدول المواصفات العام 2- البت pe في مسجل التحكم CR0 يساوي واحد معناه تفعيل النمط المحمي

قلت انه لابد من توافر جدول المداخل او جدول الاقسام ولكن ما هو:

جدول المداخل GDT جدول يتم حفظ فيه بيانات عن الأقسام او اقسام الذاكره من درجه حمايه وهل هذا القسم موجود في الذاكره الحقيقيه او الوهميه ويتم حفظ عدد الأقسام في هذه الذاكره

لم أفهم بعد:

حسننا ربما تساعدك هذه الصور علي تصور القصه وفهم نظام الحمايه المقصود

post-58631-1216902239_thumb.jpeg

ماذا بعد عن هذا الجدول

هناك خصاص اخري ايضأ مثل تحديد طول القسم او المدخل ولكن كيفيه حساب الطول قد ذكرها الأخ حكيم قبلاً وايضاً تحديد كيفيه جلب الببيانات مثلأ إذ قمت بهذه التعليمه في الأسمبلي

pop eax

معناه اخرج 32 بت من المكدس *** حيث سيتم تحديد طريقةالبرنامج في جلب البيانات هل هي بطول 32 بت كما رأينا ام بطول 16 بت إذا قمت بجعلها 16 بت في قسم النظام وانت تستخدم نواه مصنوعه ب سي/سي++ فهاذا معناه خطأ لأان السي /سي++ تجلب البيانات بطول 32بت

وهذا ليس بالنسبه للبيانات فقط بل للكل اي شفره + بيانات فلابد الا تتواجد تعليه خاصه لمسجلات 32بت في هذا القسم

*****************************************

اظن انه قد حان الوقت للبدأ في كتابه جدولنا الخاص

اولاً كيف اخبر المعالج بمكان تواجد الجدول:

لكي تخبر المعالج بمكان تواجد الجدول لابد من تحديد قيمتين هما طول الجدول ومكانه

فمكان الجدول تحدد للمعالج مكان بدء البحث عن بيانات القسم الذي يحاول البرنامج الولوج

إليه + معلومات القسم الذي يعمل في البرنامج

سؤال بسيط هل سيستمر المعالج في البحث ربما يبحث في بيانات غير بيانات الجدول

تذكر طول الجدول و بدايته فما يحددان للمعالج متي سينهي البحث

سؤال اخر كيف سأخبر المعالج بهذه البيانات

عن طريق التعليمه Lgdt [gdt] حيث lgdt عنوان المعلومتين السابقتين

سؤال اخر ما هو تكوين بيانات القسم(اي المعلومات التي تحدد درجه حمايته ....إلخ)؟

حسننأ تتكون تلك المعلومات من الاتب

البتات 
من  إلي	:  الوصف
0   15	: يتم تحديد فيها طول القسم كاملاً وطريق الحساب ذكرها الأخ حكيم
16  31	: يتم فيها تحديد وضع قيمها يحتاجه المعالج عن التحويل من العنوان الخطي إلي
			 محدد القسم:مكان البيانات وذالك لان نواه السي بلس بلس او السي تكتب العنوان الخطي 
			 نضعها بالقيمه صفر حتي لا شير إلي بيانات اخري 
32  39   :نفس السابق
40  44   :نوع القسم طولها اربع بيتات كل بت يمتلك صلاحيه معينه مدرجه بلأسفل
			اولاً صلاحيات اقسام البيانات
			 0000  تعني انه للقرأه فقط
			0001 للقرأه ويمكن الوصول إلي معلوماته
			0010 للقرأه والكتابه
			0011 للقرأه والكتابه ويمكن الوصول إليه
			 0100 للقرأه فقط
			 0101للقرأه ويمكن الوصول
			 0110 قرأه وكتابه
			 0111 للقرأه والكتابه ويمكن الوصول 
			 اقسام الشيفره
			 1000 للتنفيذ فقط
			 1001 للتنفيذ فقط ويمكن الوصول
			1010 للتنفيذ والقرأه
			1011 للتنفيذ والقرأه وإمكانيه الوصول
44  44  : قسم نظام 1=نعم  0 =لا وفي حالتنا سنضع نعم
45  46  :درجه الحمايه 0 تعني انها درجه حمايه للنظام
						 1 تعني درجه حمايه لخدمات النظام
						 2 "	 "	 "	 "	  "
						 3 درجه حمايه البرامج
47 47 :هل القسم موجود في الذاكره ام انه في ذاكره وهميه ربما تكون علي القرص الصلب 1 =نعم
48 51:اخر رقم في الطول (اي طول القسم)
52 52 :محجوز لمعالج 64 بت
53 53 : "	   "	 "  "
54 54: طريقه جلب البيانات 1 تعني بطريقه 32بت و 0 تعني 16
55 55 : البت الذي يحدد طريقه حساب الحجم
56 63 :نفس البيتات من 16 إلي 31

هكذا قد عرفنا مكونات بيانات القسم

سؤال كيف اكتب الجدول الان

هنا الان مثال لطريقه كتابه الجدول وحاول مقارنته مع السابق

dw  0,0,0,0
db  0xFF,0xFF,0,0,0,10011011b,11011111b;limit(0:15),limit(0:15),base(16:31),base(32:39),base(56:63),47 46 45 44 43 42 41 40,55,54,53,52,51,50,49,48,base(65:63)
قمت بوضع ترتيب البيتات حتي تكون مثله

قمت بإعداد جدولي وتحميل كيف امر إلي النمط المحمي

كما قلنا من قبل عن طريق جعل البت pe = 1 اي تفيعل النمط المحمي

مثال
mov eax,CR0
or al,1
mov CR0,eax

كيف اشغل النواه(كيف احسب محدد القسم)

اولاً احضر رقم ترتيب المدخل (مثلا انت في جدولك كتبت 10 مداخل ونواتك في المدخل رقم 10 فالرقم 10 هو المقصود) ثم حول للبيناري = 1010 اضف من جه اليمين 0 إضافيه ثم احضر درجه افضليه القسم وحولها للبيناري = 00 اضفها لليمين في النهايه البيتات = 1010000 هكذا هي بيتات

محدد القسم بالتحويل إلي الهكس = 0x50

نرجوا ان نكون قد وفينا هذه المره في الشرح اي استفسار :lol:

−1

my new site click here

#102

شكرا جزيلا أخي halwa أنا الآن أشعر بسعادة غامرة :happy:

برنامج المحادثة المفضل عندي هو skype

ابحث عن aymen.hakim

الشرح عن النمط المحمي رائع

للأسف سأضطر للتغيب بعض الايام

وعند عودتي سأبعث لك برسالة على بريدك بالمنتدى إن شاء الله

مشكور جدا على المجهود

إلى اللقاء

#103

السلام عليكم ورحمه الله وبركاته

:wub: الحمد لله ان السعاده تغمرك الأن وان الشرح افضل من السابق

ولكن الخطا :S خطأي منذ البدايه ظننت ان معظم من سيشتركون ممن يحبوون الحفظ وليس الفهم

ونرجو الا تتطيل في الغياب

تم تعديل هذه المشاركة بواسطة halwa في 25 يوليو 2008 في 04:07

my new site click here

#104

بسم الله الرحمن الرحيم

أسف علي تأخري لان شركه الانترنت tedata قامت بقطع الانترنت عنا وقد قمت بوضع هذا الدرس من احد مقاهي الانترنت بسبب عدم دفعنا الاشتراك

**********************************************

ملحوظه مهمه يج ان تكون قد قرأت معنا الدرس السابق الخاص ب linker وملف makefile وgrub

*********************************************

وعندي حل افضل من ربما يكون افضل من الاخرين وهو فتح موضوع اخر يحتوي علي كافه الأسئله وهذا الموضوع يخصص للشرح

ونرجو دعم احد خبراء السي/سي++ لنا في شرح الاشياء الغامضه طبعاً في لغه السي /سي++ وليس انظمه التشغيل

**********************************************

درسنا اليوم عن الشاشه النصيه حيث سنقوم بدعم الشاشه النصيه.

درس اليوم يحتوي علي الملفات الاتيه

boot.asm

main.cpp

video.cpp

system.cpp

inc/video.h

inc/system.h

*********************************************

اولاَ ملف boot.am

هنا شرح الملف Grub mlutiboot

********************************************

ملف main.cpp لا يحتوي الكثير

#include "inc/system.h"
#include "inc/video.h"

extern "C" void Hmain()	 //تصدير إسم النواه وفي حالتنا Hmain
{							
   puts('W');				   // طباعه حرف علي الشاشه
								   // الكثير من يقول انه لا يمكن استخدام تلك الدوال في كتابه انظمه التشغيل ولكن ...... انظر الباقي 
   while(1);					 // دوره لا نهائيه الهدف منها هو توقف النواه عن العمل
}

*******************************************

ملف system.h سوف اطلق عليه ملف التعريفات

#ifndef _H_system_					 // أمر توجيه للمترجم معناه إذا لم يتم تعريف _H_system_
#define _H_system_					 // قم بتعريفها
												// الهدف من ذاك هو منع تعريف هذا الملف في النواه مره اخره
typedef unsigned char  uchar;	   // تعريف نوع جديد من المتغيرات وسيكون اسمه uchar
typedef unsigned short ushort;	  // كما في السطر بلأعلي
typedef unsigned int	uint;		  // كما في السطر بلأعلي

void  memset(uchar *dest,uchar val,int count);
											   /*  الهدف من هذه الداله وجعل احد عناوين الذاكره يساوي قيمه معينه 
													في البدايه قمت بتعريف المتغير dest 
													 والذي يحمل عنوان الذاكره الذي نريد نسخ قيمه إليه
													 val  القيمه التي سيتم نسخها
													 عدد تكرارات النسخ   ملحوظه كلما ذاد عدد
													 مرات النسخ سيزيد العنوان
													example: 
													العنوان المقصود 00001 وعدد التكرارات 5 فستم النشخ في العناوين التاليه 
													 كما يلي بالقيمه a
												   00001  = A
												   00002  = A
												   ... 
												   00005   = A
												 */
void	memcpy(uchar *dest,uchar *src,int count); // نفس شرح السابق تقريباً

*********************

ملف system.cpp الكود الحقيقي للدول التي عرفت بلأعلي

void  memset(uchar *dest,uchar val,int count)
{
		int i;
		for(i=0;i<= count;i++)
	   {
		  dest=val;
	   }
}
void	memcpy(uchar *dest,uchar *src,int count)
{
		int i;
		for(i=0;i<= count;i++)
	   {
		  dest=src;
	  }	  
}

******************

كل هذا :angry: ولم تبدأ في شرح الشاشه النصيه لما؟

حسنناً نرجو الهدوء قليلاً (حقيقة لا اعرف من اي ابدا)

الشاشه النصيه تلك اشاشه السوداء التي لا نري الألوان فيها إلا صدفه تتكون تلك الشاشه من طول 80 وعرض 25

ماذا تعني ب 80 و 25؟ اي انها تستطيع ان تحتوي علي احرف بطول 25*80 اي 2000 حرف

طلب بسيط ممكن صوره ؟ انظر المرفقات

سؤال كيف اقو بإظهار حرف علي الشاشه حسننأ عن طريق جعل العنوان 0xb8000 برقم الحرف في جدول أسكي كود متبوعا بلون الحرف طبعا اول سؤال يأتي إليك كيف احمل احرف اخري ؟

لكي تقوم بتحميل أي حرف ليظهر علي الشاشه استخدم هذا المعادله لتحصل علي موقعه

(السطر * 80 ) + الموقع

وتقم بإضافته للعنوان السابق

مثال نريد طباعه احد الحروف في السطر 5 بعد 10 مسافات

(5*80) + 10 = 410 نقوم بإضافته للعنوان السابق فيكون

0xb8410 نقوم بتحميله برقم الحرف والعنوان 0xb8411 بلون الحرف

للخلاصه

العناوين الزوجيه للحروف والعناوين الفرديه بلون الحرف

نهايه الموضوع :

ارجوا ان اكون قد وفيت بهاذا الشرح وأي اسئله يجب ان تكون علي الخاص او في موضوع اخر

وطلبي كتابه كود يستغل الشرح السابق في طباعه احرف علي الشاشه قبل وضع الكود

******************************************************

Halawa oprating system سوف اقوم بوضعه عن قريب إن شاء الله

//////////////////////////////////////////////////////

my new site click here

#105

نصيحة ، بدل من شرح نظام التشغيل هنا ، ليقرأ كل واحد جزء تتفقون عليه ، وأي واحد عنده استفسار يسأل.

هكذا أفضل ، حتى يكون الموضوع عملي.

System Engineer

Red Hat Certified Engineer

Red Hat Certificate Number

805010381752078

#106

اعرف قصدك أخ برق

فكل واحد يقرأ عن جزء معين واحد يقرء عن الشاشه النصيه وواحد يقرا عن جدول Gdt

وواحد يقرأ عن Gui وغير

لأا اظن هذا بينفع تقول لماذا لان كل جزء مرتبط بما قبله إرتباط وثيق

فلا يمكن لاحد البرمجه وينسي المرجم او المفسر كيف سيعمل برنامجه

my new site click here

#107

لا ، ليس هذا قصدي ، قصدي أنكم كلكم تقرؤون نفس الجزء ، وتتناقشوا فيه ، وإذا لم يفهم أخد يقوم الآخر بإفهامه.

على العموم ، دعواتي معاكم

System Engineer

Red Hat Certified Engineer

Red Hat Certificate Number

805010381752078

#108

السلام عليكم

وأخيرا عدت ياأخ halwa :happy:

فكرة جيدة فعلا

أخ برق بما أنك مشرف قسم اللينكس قد تستطيع مساعدتنا في هذا الأمر :wub:

وشكرا

#109
اقتباس
أخ برق بما أنك مشرف قسم اللينكس قد تستطيع مساعدتنا في هذا الأمر

لدينا في القسم موضوع اسمه الطريق إلى linux kernel .

يمكنك متابعته، وسأبدأ قريبا مع شخص واحد فقط ، لكنه مؤهل تماما ومحترف.

System Engineer

Red Hat Certified Engineer

Red Hat Certificate Number

805010381752078

#110

اين الكود الذي قمتم بكتابته انا في الانتظار حتي اقوم بوضع الكود الذي استخدمه في دعم الشاشه النصيه

اخ برق اتمني ان اكون احد المشاركين في مشروعك هذا ولكن سبب عدمن اشتراكي هو انه ليس لي خبره بلينكس نهائياً :cry:

my new site click here

#111

بسم الله الرحمن الرحيم

يبدو انه لا احد يريد المشاركه معي

بالنبسبه لملف الفيديو والذي كنت اريد منكم ان تقوقموا بكتابته ولم يضعه احد سوف اقوم بوضعه

وها هو الكود

unsigned char *vmem = (unsigned char*)0xb8000;
int x=0,y=0;
void puts(char c)
{
	if (c == '\n')
	{
	   x=0;y++;
	}else if( c== '\b')
	{
	   if(x != 0)x--;
	}else if( c==  '\t')
	{ 
	  x += 4;
	}else if (c >= ' ')
	{
		int address = ((y*80)+x)*2;
		vmem[address]  = c;
		vmem[address+1] = 0x1F;
	   x++;
	}
	if(x > 80)
	{
		 x=0;y++;
	}
	if(y > 25)
	{
	   x=0; y= 0;
	}
}

في البدايه تعريف للداله putc ومهمتها كتابه حرف علي الشاشه وتأخذ عامل وهو الحرف

وقد تم تعريف قبلها متغيرين وهما الاذان المكان الحالي الذي سيتم الكتابه فيه وقد تم جعل قيمتهما = صفر اي ان المكان الحالي = اعلي يسار الشاشه

ويوجد قبلهما مؤشر يشير إلي العنوان الخطي للشاشه النصيه في الذاكره

***********************************

شرح الداله putc

في البدايه يوجد عده شروط علي محتوي المتغير c

اول شرط إذاكان = n\ فإنه يقوم بالنزل سطر جديد عن طريق الأمر ++y والرجوع إلي اول السطر عن طريق ++x اي ان العمل يتم وكأن الشاشه شبكه تربيعيه

والأن حاول ان تفهم بقيه الشروط

نأتي إلي اخر شرط عن المتغير cإذا كانت القيمه المحمله ابر من او تساوي رقم المسافه في جدول اسكي اي اكبر من 0x20 يقوم بطباعهتها علي الشاشه

في البدابه يقوم بحساب الموقع الحالي عن طريق المعادله السابقه (في الدرس السابق) (السطر * 80) + الموقع * 2 لماذا *2 لان عنوان الشاشه النصيه لا يحتوي فقط علي عناوين للحرف فقط بل للألون ايضاً فتكون المعادله في النهايه (y *80) + x )) *2 ثم نقوم بألامر ++x حتي لا نكب الحروف كلها في مكان واحد

الشرطين في النهايه حتي لا يتعد الموقع الحالي حدود الشاشه النصيه

***********************************

الان حاول بنفسك كتابه الدله printf وفكرتها كالأتي حساب طول النص(مثال الداله strlen) يقوم بتكرار الطباعه إلي ان يصل إلي الحرف 0\

حاول كتابتهمل حتي اقوم بإرفاق الكود المصدري للنظام الحالي

my new site click here

#112
اقتباس
السلام عليكم

اخي halwa كل احترام الك

استمر في التفسير والشرح

انا لا افهم الكثير مما تشرح لكن اود ان اشكرك على الشرح الجيد !!

ارجو من الاعضاء المعنين المتابعة في العمل

شكرا الى الجميع

بسم الله الرحمن الرحيم

من الواضح انه لا يوجد إلي حل واحد وهو وضع الدرس في ملف pdf لسببين

1-سوف يكون الشرح وافي اكثر.

2-صاحب مركز الانترنت لن يزعجني بكلمه(انتهي الوقت)

my new site click here

#113

يبدو اني قد تاخرت في الرد ولكن لا تقلقوا اني موجود والحمد لله

قديقول البعض اني قد تركت الموضوع ولكن لا تقلقوا فلو اني قد تركته فعلاً لما كنت وضعت هذا الرد :D :huh:

لقد ارفقت الدرس وهو بهئه بي دي اف

ملحوظه لقد قمت بوضع اشياء مبهمه حاول ان تفعلها بنفسك ثم قم بإرسالها لي

tsrc.rar

my new site click here

#114

بسم الله ما شاء الله عليك اخى والله بارك الله فيك وفى تعبك الكتاب اكثر من رائع وباذن الله حقراءه وساحاول الى الانضمام اليكم قريبا جدا

اشكرك جدا اخى

amdvsintel22.jpg

--i use AMD--

لا اله الا الله محمد رسول الله

أستعن بالله و لا تعجز

تابعنى على تويتر

***

#115

شكرا جزيلا لك أخي halwa على هذا الجهد المبذول.

وآسف إذا كان الرد متأخرا فقد أصبحت زيارتي قليلة للمنتدى هذه الأيام.

أنتظر الدرس الموالي

وشكرا

#116

العفو شباب لا شكر علي واجب وسوف يتحقق حلمكم الذي طلبتموه في البدابه وهو صناعه محرك الاوامر

**********

عندي طلب بسيط لمن كلن لهم محاولات سابقه في مجال برمجه انظمه التشغيل

وهو ال paging اريد مساعده فيه من فضلكم لان معظم محاولتي فشلت فيه

وارجو وضعه في المنتدي حالياً اقوم بالرسم علي الشاشه وقد قمت برسم الحرف H اول حرف من حروف كلمه Halawa

وهو بهذا الشكل

|| ||

|| ||

||-----||

||-----||

|| ||

|| || :D

my new site click here

#117
halwa كتب:
عندي طلب بسيط لمن كلن لهم محاولات سابقه في مجال برمجه انظمه التشغيل

وهو ال paging اريد مساعده فيه من فضلكم لان معظم محاولتي فشلت فيه

صراحتا اخى كنت اتمنى ان اكمل معك شئ ولكن انا حاليا فى الدراسة النظرية وليس بوسعى مساعدتك فى الوقت الحالى ربما اسبوع او اسبوعين ان شاء الله واكن مؤهل للبدء فى ال paging impliemtation

اطيب المنى :)

amdvsintel22.jpg

--i use AMD--

لا اله الا الله محمد رسول الله

أستعن بالله و لا تعجز

تابعنى على تويتر

***

#118

halwa استمر ، أتمنى لك التوفيق :)

#119

اخي ان كنت تقصد الـMemory Paging فقد قرأت عن هذا الموضوع من قبل وفهمت اكثره نظرياً لكن لم اطبق عملي ,, سأضع ما توصلت اليه اذا سعفني الوقت (رمضان بقى وكل سنة وانت طيب :D ) .

mov eax, dword ptr ds:[0xffdf0308]

jmp dword ptr [eax+0xfc]

#120

حسننا انا موافق وارجو وضع المعلومات في اقرب وقت ممكن قبل دخول الدراسه

وها هو الدرس الرابع

اسف لن استطيع ارفق السورس كود الان

2.pdf

تم تعديل هذه المشاركة بواسطة halwa في 12 سبتمبر 2008 في 16:16

my new site click here

#121

يا اخي العزيز هذا ليس أمر صعب وهو كان صعب عند الأجانب ولكن هم انشئو مؤسسات ويعمل في هذه المؤسسات مبرمجين كثيراً ولو يوجد مؤسسة عربية لو لم يكن بالأمر الصعب ولكنه يحتاج اشخاص كثر انا افكر اني افتح مؤسسة للمبرمجين العرب

#122

بالفعل نرى دوما مواضيع لنفس الاتجاه

ولكن نأمل أن يعبر أحدهم جسر المناقشات .. نحو التنفيذ ..

والله المستعان

لله في الآفاق آيات لعـــل = أقلهـــا هو ما إليه هداكا

ولعل ما في النفس من آياته = عجبٌ عجابٌ لو ترى عيناكا

والكون مشحون بأسرار إذا = حاولت تفسيراً لهــا أعياكا

#123

كل ما يحتاجه الأعضاء للتقدم أكثر في هذا المجال هو القيام بالبحث

إستعملوا جوجل يا ناس

كل شيئ موجود على النت

لن يتطور العرب إلا إذا أحسنوا إستغلال البحث في الأنترنت لصالحهم

#124

السلام عليكم

ممكن كيفية تحويل كود سي إلى ملف بيناري لأنني لم أستطع تجريب النواة وهي بنمط elf.

أو كيفية تنصيب grub على virtual machine وتحميل النواة بداخله.

وشكرا

#125

في البدابه اسف علي التأخير (الدراسه هي السبب)

ثنانياً ولنقم بالرد علي الاسئله

1-لكي تقوم بالتحويل من elf إلي بيناري ابحث في ملف الربط او ملف ال Makefile عن elf-i386 واستبدلها ب binary وهتناك انولع اخري مثل

pe-i386

pei-i386

بالنسبه لتنصيب grub حاليأ شرحها كبير ويمكنك الاستعانه بشخص يفهم جيداًًَ في هذا البرنامج + لينكس

ملحوظه من الان فصاعداً سوف اعرض الفكره وان تقوم بتطبيقها بنفسك وسوف اعرض ايضاً فكره التأكد من عمل الكود الذي قمت بكتابته

my new site click here

مواضيع مشابهة