كيفية الحصول على مدخلات لوحة المفاتيح مع x86 المعدن الجمعية ؟

StackOverflow https://stackoverflow.com/questions/217731

سؤال

أنا في عملية محاولة الإختراق معا أول بت من النواة.لدي حاليا كامل نواة جمعت أسفل رمز C ، لقد تمكنت من الحصول عليه عرض النص في إطار وحدة التحكم وكل ذلك غرامة الخير.الآن, أريد أن بدء قبول مدخلات لوحة المفاتيح لذلك أنا يمكن أن تجعل في الواقع استخدام بعض الشيء والحصول على الذهاب في إدارة العملية.

أنا باستخدام DJGPP تجميع و تحميل مع نكش.أنا أيضا باستخدام قطعة صغيرة من الجمعية الأساس الذي يقفز مباشرة إلى تجميع التعليمات البرمجية C و أنا سعيد من هناك.

كل البحث الذي قمت به ويبدو أن نشير إلى ISR بمبلغ 0x16 أن تقرأ في الحرف التالي من لوحة المفاتيح العازلة.من ما أستطيع أن أقول, هذا هو المفترض لتخزين قيمة ASCII في آه ، keycode في al, أو شيء بهذا المعنى.أحاول رمز هذا باستخدام الروتينية التالية مضمنة في الجمعية:

char getc(void) 
{
    int output = 0;

    //CRAZY VOODOO CODE
    asm("xor %%ah, %%ah\n\t"
        "int $0x16"
        : "=a" (output)
        : "a" (output)
        : 

        );

    return (char)output;
}

عند هذا يسمى رمز الأساسية تعطل على الفور.(أنا على التوالي على فيرتثلبوإكس ، لم تشعر بالحاجة إلى محاولة شيء من هذا الأساسية على الأجهزة الحقيقية.)

الآن أنا فعلا بعض الأسئلة.لا أحد يستطيع أن تخبرني إذا (منذ قانون بلدي انطلقت من نكش) أنا تشغيل في الوضع العادي أو الوضع المحمي في هذه اللحظة.لم تقفز بطريقة أو بأخرى ، كنت تخطط لتشغيل في الوضع الحقيقي حتى حصلت عملية معالج إعداد.

حتى على افتراض أن أنا على التوالي في الوضع الحقيقي ، ماذا أفعل الخطأ و كيف يمكنني إصلاح ذلك ؟ أنا فقط بحاجة الأساسية getc الروتينية ، ويفضل أن يكون غير مؤمن ، ولكن سوف يكون موضع سخرية إذا جوجل يساعد على هذا.مرة واحدة أستطيع أن أفعل ذلك, أنا يمكن أن تفعل بقية من هناك.

أعتقد أن ما أنا أسأل هنا هل أنا في أي مكان بالقرب من الطريق الصحيح ؟ كيف يمكن للمرء عموما أن تذهب نحو الحصول على مدخلات لوحة المفاتيح على هذا المستوى ؟

تحرير:OOhh...لذلك أنا على التوالي في الوضع المحمي.وهذا بالتأكيد ما يفسر تحطم محاولة الوصول إلى الوضع الحقيقي المهام ثم.

لذا أعتقد أنا أبحث عن كيفية الوصول إلى لوحة المفاتيح IO من الوضع المحمي.وأنا قد تكون قادرة على العثور على بلدي, ولكن إذا كان أي شخص يحدث أن تعرف تتردد.شكرا مرة أخرى.

هل كانت مفيدة؟

المحلول

إذا كنت ترجمة مع دول مجلس التعاون الخليجي، إلا إذا كنت تستخدم ".code16gcc" مجنون خداع استخدامات نواة لينكس (الذي أشك كثيرا)، لا يمكن أن يكون في الوضع الحقيقي. إذا كنت تستخدم مواصفات GRUB متعدد أنظمة التشغيل، GRUB نفسها التحول إلى الوضع المحمي بالنسبة لك. لذا، وكما أشار آخرون، سيكون لديك لاجراء محادثات مع وحدة تحكم لوحة المفاتيح 8042 متوافق مع / الماوس مباشرة. إلا إذا كان لوحة المفاتيح USB / الماوس وتعطيل 8042 مضاهاة، حيث كنت في حاجة الى كومة USB (ولكن يمكنك استخدام بروتوكول "التمهيد" لوحة المفاتيح / الماوس، وهو أبسط).

وقال لا أحد الكتابة كانت نواة نظام التشغيل بسيطة.

نصائح أخرى

رمز كنت قد حصلت هناك محاولة الوصول إلى الوضع الحقيقي BIOS الخدمة.إذا كنت تعمل في الوضع المحمي ، والتي من المرجح معتبرا أن ما تقوم به هو كتابة النواة ، ثم المقاطعة لن تنجح.سوف تحتاج إلى القيام بأحد الإجراءات التالية:

  • صوت هائل وحدة المعالجة المركزية في الوضع الحقيقي ، والتأكد من الجدول متجه المقاطعة هو الصحيح ، واستخدام الوضع الحقيقي كود لديك أو
  • الكتابة الخاصة بك المحمية وضع لوحة المفاتيح معالج (أياستخدام في/خارج التعليمات).

الحل الأول هو الذهاب إلى إشراك وقت أداء النفقات العامة صه الثانية سوف تتطلب بعض المعلومات عن لوحة المفاتيح IO.

ولقد قطعة من GeekOS الذي يبدو للقيام

In_Byte(KB_CMD);

ثم

In_Byte(KB_DATA);

ولجلب scancode. I طرحها: keyboard.c و <لأ href = "HTTP : //gargoyle.ath.cx/~aes/keyboard/keyboard.h "يختلط =" نوفولو noreferrer "> keyboard.h . KB_CMD وKB_DATA يجري 0x64 0x60 وعلى التوالي. أنا ربما يمكن أن تشير أيضا إلى أن يتم ذلك في معالج المقاطعة لINTR: 1

وأنت تفعل الشيء الصحيح، ولكن يبدو لي أن أذكر أن DJGPP يولد سوى إخراج الوضع المحمي، التي لا يمكنك استدعاء المقاطعات من. يمكنك إسقاط إلى الوضع الحقيقي مثل الآخرين قد اقترح، أو تفضل لمعالجة الجهاز مباشرة؟

لأغراض التوضيح، لنفترض أنك تكتب <م> كل شيء في لغة التجميع نفسك، محمل التمهيد والنواة (* السعال * لقد فعلت هذا).

في الوضع العادي، يمكنك الاستفادة من إجراءات المقاطعة التي تأتي من BIOS. يمكنك أيضا استبدال ناقلات المقاطعة مع بنفسك. لكن كل رمز هو رمز 16 بت، وهو <م> لا ثنائي متوافق مع رمز 32 بت.

عند القفز من خلال بعض الأطواق حرق للوصول الى الوضع المحمي (بما في ذلك إعادة برمجة وحدة تحكم المقاطعة، للالتفاف على حقيقة أن IBM تستخدم المقاطعات محفوظة إنتل في PC)، لديك فرصة لاقامة 16- و شرائح رمز 32 بت. وهذا يمكن أن تستخدم لتشغيل التعليمات البرمجية 16 بت. لذلك يمكنك استخدام هذا للوصول إلى getchar يقطع!

... ليس تماما. لهذا يقطع على العمل، كنت في الواقع في حاجة إلى بيانات في منطقة عازلة لوحة المفاتيح التي تم وضعها من قبل ISR مختلفة - واحد التي يتم تشغيلها بواسطة لوحة المفاتيح عند الضغط على مفتاح. هناك العديد من القضايا التي تمنع الى حد كبير الذي تستخدمه BIOS ISRS كما ISRS الأجهزة الفعلية في الوضع المحمي. لذلك، إجراءات لوحة المفاتيح BIOS عديمة الفائدة.

والمكالمات BIOS الفيديو، من ناحية أخرى، على ما يرام، لأنه لا يوجد أي عنصر الناتجة عن الأجهزة. لديك لإعداد قطعة رمز 16 بت ولكن إذا كان هذا هو تحت السيطرة بعد ذلك يمكنك تبديل أوضاع الفيديو وهذا النوع من الشيء باستخدام المقاطعات BIOS.

عودة إلى لوحة المفاتيح: ما تحتاج (على افتراض مرة أخرى أن كنت تكتب كافة التعليمات البرمجية) هو لكتابة تشغيل لوحة المفاتيح. إلا إذا كنت مازوشي (أنا واحد) ثم لا تذهب إلى هناك.

واقتراح: محاولة كتابة نواة تعدد المهام في الوضع العادي. (هذا هو وضع 16 بت.) يمكنك استخدام جميع المقاطعات BIOS! لم تحصل على حماية الذاكرة ولكن لا يزال بإمكانك الحصول تعدد المهام الوقائية التي ربط المقاطعة جهاز ضبط الوقت.

مجرد فكرة: النظر في GRUB لمصدر DOS (وasm.s)، وconsole_checkkey وظيفة يستخدم INT 16H Function 01 BIOS، ولا تعمل 00، كما تحاول أن تفعل. ربما كنت ترغب في معرفة ما اذا كان مفتاح ينتظر أن يكون الإدخال.

والرمز console_checkkey هو وضع وحدة المعالجة المركزية إلى الوضع الحقيقي من أجل استخدام BIOS، كما @ اقترح skizz .

ويمكنك أيضا محاولة استخدام وظائف GRUB مباشرة (إذا كان لا يزال تعيينها في الوضع الحقيقي).

ومذكرة بشأن مصدر التجمع القراءة: في هذا الإصدار

movb    $0x1, %ah

وسائل نقل بايت ثابت (0x1) لتسجيل %ah

ووconsole_checkkey من asm.s GRUB:

/*
 * int console_checkkey (void)
 *  if there is a character pending, return it; otherwise return -1
 * BIOS call "INT 16H Function 01H" to check whether a character is pending
 *  Call with   %ah = 0x1
 *  Return:
 *      If key waiting to be input:
 *          %ah = keyboard scan code
 *          %al = ASCII character
 *          Zero flag = clear
 *      else
 *          Zero flag = set
 */
 ENTRY(console_checkkey)
  push  %ebp
  xorl  %edx, %edx

  call  EXT_C(prot_to_real) /* enter real mode */

  .code16

  sti       /* checkkey needs interrupt on */

  movb  $0x1, %ah
  int   $0x16

  DATA32    jz  notpending

  movw  %ax, %dx
  //call    translate_keycode
  call  remap_ascii_char
  DATA32    jmp pending

notpending:
  movl  $0xFFFFFFFF, %edx

pending:
  DATA32    call    EXT_C(real_to_prot)
  .code32

  mov   %edx, %eax

  pop   %ebp
  ret

مثال للاقتراع وحدة تحكم لوحة المفاتيح:

Start:
      cli
      mov al,2        ; dissable IRQ 1
      out 21h,al
      sti

;--------------------------------------
; Main-Routine
AGAIN:
      in al,64h       ; get the status
      test al,1       ; check output buffer
      jz short NOKEY
      test al,20h     ; check if it is a PS2Mouse-byte
      jnz short NOKEY
      in al,60h       ; get the key

; insert your code here (maybe for converting into ASCII...)

NOKEY:
      jmp AGAIN
;--------------------------------------
; At the end
      cli
      xor al,al       ; enable IRQ 1
      out 21h,al
      sti
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top