Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Getting input with GNU-EFI

719 views
Skip to first unread message

Somebody Smart

unread,
Jan 25, 2017, 4:36:18 PM1/25/17
to
Hello,

I want to create a simple OS with GNU-EFI, and so far I can output text, but any good OS (or bootloader, for that matter) needs to accept input in some way. How can I use the SystemTable's ConIn and call_uefi_wrapper to accept input? Even if it just outputs it right back, it's a start.

Thank you!

Benjamin David Lunt

unread,
Jan 25, 2017, 5:17:34 PM1/25/17
to

>>>>>>>>>>>>>>
"Somebody Smart" <brucec...@gmail.com> wrote in message
news:cb68e2fc-e394-4bdc...@googlegroups.com...
"Somebody Smart"... I like that. Not very many people are as smart
as they think they are, especially me :-)

Anyway, here is the code I use:

// ReadKeyStroke returns EFI_NOT_READY if no key available
// ReadKeyStroke returns EFI_SUCCESS if a key is available
// It will not wait for a key to be available.
EFI_STATUS kbhit(struct EFI_INPUT_KEY *Key) {
return gSystemTable->ConIn->ReadKeyStroke(gSystemTable->ConIn, Key);
}

// Wait for a key to be available, then read the key using ReadKeyStroke
EFI_STATUS getkeystroke(struct EFI_INPUT_KEY *Key) {
WaitForSingleEvent(gSystemTable->ConIn->WaitForKey, 0);
return gSystemTable->ConIn->ReadKeyStroke(gSystemTable->ConIn, Key);
}


Ben

P.S. I don't use the wrapper. I use a variation of Alex's C compiler
which produces the correct function parameter list order.

--
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Forever Young Software
http://www.fysnet.net/index.htm
http://www.fysnet.net/osdesign_book_series.htm
To reply by email, please remove the zzzzzz's

Batteries not included, some Assembly required.


Somebody Smart

unread,
Jan 28, 2017, 8:25:46 PM1/28/17
to
Hey,

Your solution somewhat works, at least on my computer. It says "Hello World!" like it should, but when I press a key (like Enter) it just spams some characters with a few @s in between. I have a (pretty bad) picture here: https://goo.gl/photos/EEvDTg96mjuieUFaA

Anyways, would I need to use uefi_call_wrapper or do anything to make it work on x64, or fix it in another way? If it helps, I have an i5-4200U.

Thanks! :D

Benjamin David Lunt

unread,
Jan 28, 2017, 9:05:39 PM1/28/17
to

"Somebody Smart" <brucec...@gmail.com> wrote in message
news:072e810d-ff3a-49e5...@googlegroups.com...
The wrapper is for the compiler, not the processor (so to speak).
The wrapper places the parameters on the stack in the correct order.
UEFI requires the parameters to be placed on the stack from
right to left. Some compilers, place the parameters on the
stack from left to right.

This is called "calling convention" and has different
types.

Since UEFI is (mostly) MS created, it must use the right to left
calling convention.

As for printing characters to the screen when you press Enter,
this could be anything and I don't have a clue to tell you where
to start looking without looking at some code.

Check your compiler first, the "calling convention" should be
right to left.

Ben



Somebody Smart

unread,
Jan 29, 2017, 9:07:56 AM1/29/17
to
Hello again,

How exactly would I do that? I'm not sure how to check the calling convention. If it matters (which I think it might, sorry for not mentioning it before), I'm getting some warnings from make and cc, here they are: http://pastebin.com/3V3QQ0Qm

Anyways, thank you for being patient. If you need the source code, let me know.

Thank you!

Benjamin David Lunt

unread,
Jan 29, 2017, 3:20:09 PM1/29/17
to

"Somebody Smart" <brucec...@gmail.com> wrote in message
news:40ffb197-1041-4244...@googlegroups.com...
> Hello again,
>
> How exactly would I do that? I'm not sure how to check the calling
> convention. If it matters (which I think it might, sorry for not
> mentioning it before), I'm getting some warnings from make and cc, here
> they are: http://pastebin.com/3V3QQ0Qm
>
> Anyways, thank you for being patient. If you need the source code, let me
> know.

If you look at
https://en.wikipedia.org/wiki/X86_calling_conventions
You will see that most likely GCC is using the RtL convention, which
is correct. However, you need to make sure. Use the parameters
you see on that page to indicate that it is.

Second, it may not be your calling conventions that is in error.
If you see a string printed when you call the print string service,
you probably are sending the correct parameters.

Please post a little code here in this group so that we can see
what you are doing.

Ben

Somebody Smart

unread,
Jan 30, 2017, 6:54:56 AM1/30/17
to
Hey,
I'll post the two parts I think are necessary. I'm #including efi.h, efilib.h and efiapi.h.

-- Part 1
EFI_SYSTEM_TABLE *SystemTable;

// Wait for a key to be available, then read it
EFI_STATUS getKeyStroke(EFI_INPUT_KEY *Key) {
WaitForSingleEvent(SystemTable->ConIn->WaitForKey, 0);
return SystemTable->ConIn->ReadKeyStroke(SystemTable->ConIn, &Key);
}
-- End P1

(I define conout, used below, around here)

-- Part 2
for(;;) {
getKeyStroke(&input);
uefi_call_wrapper(conout->OutputString, 2, conout, input.UnicodeChar);
count++;
}

If you need more, I can post more.

Thank you again.

Benjamin David Lunt

unread,
Jan 30, 2017, 6:40:25 PM1/30/17
to

"Somebody Smart" <brucec...@gmail.com> wrote in message
news:28690862-c470-48c1...@googlegroups.com...

> -- Part 2
> for(;;) {
> getKeyStroke(&input);
> uefi_call_wrapper(conout->OutputString, 2, conout, input.UnicodeChar);
> count++;
> }

So, you are still indeed calling the wrapper. Depending on the library
you include, the code you have, and the compiler you are using, you
may not need to call the wrapper.

Have a look at this page:
http://www.rodsbooks.com/efi-programming/efi_services.html

A little more than halfway down is a subject header:
"An example of using UEFI services"

Read that section. It tells you all about why the wrapper is there and
if you can get rid of it.

My code calls no libraries. I wrote all of the code myself using
references to other documentation and code. Therefore, no wrapper
is necessary.

Hope this helps,
Ben


Somebody Smart

unread,
Jan 30, 2017, 8:45:29 PM1/30/17
to
Hello,

I do need the wrapper, as far as I can tell, because if I remove it the messages stop appearing completely. After adding uefi_call_wrappers to EVERYTHING, though, the "checkerboard" just gets worse. Is this just something bizarre with my computer or something?

However, I think that part of the issue is in your getKeyStroke function as, although I'm sure it works in 32-bit systems, it has an incompatible pointer error at &Key; it says the following:

warning: passing argument 2 of ‘SystemTable->ConIn->ReadKeyStroke’ from incompatible pointer type [-Wincompatible-pointer-types]
return SystemTable->ConIn->ReadKeyStroke(SystemTable->ConIn, &Key);
^
main.c:15:70: note: expected ‘EFI_INPUT_KEY * {aka struct <anonymous> *}’ but argument is of type ‘EFI_INPUT_KEY ** {aka struct <anonymous> **}’

Finally, I plan for my OS (or at least the bones of it) to be 64-bit.

Thank you!

Benjamin David Lunt

unread,
Jan 30, 2017, 11:32:30 PM1/30/17
to

"Somebody Smart" <brucec...@gmail.com> wrote in message
news:5986c57f-f96d-4557...@googlegroups.com...

> Hello,
>
> I do need the wrapper, as far as I can tell, because if I remove
> it the messages stop appearing completely. After adding
> uefi_call_wrappers to EVERYTHING, though, the "checkerboard"
> just gets worse. Is this just something bizarre with my computer
> or something?
>
> However, I think that part of the issue is in your getKeyStroke
> function as, although I'm sure it works in 32-bit systems, it has
> an incompatible pointer error at &Key; it says the following:
>
>warning: passing argument 2 of ‘SystemTable->ConIn->ReadKeyStroke’
> from incompatible pointer type [-Wincompatible-pointer-types]
> return SystemTable->ConIn->ReadKeyStroke(SystemTable->ConIn, &Key);
>
>
> Finally, I plan for my OS (or at least the bones of it) to be 64-bit.

Just because you call the wrapper and it works better than when you
don't, doesn't mean you need to call the wrapper.

Did you find out if you really need to call it? Not by simply calling
it and seeing if it works, but by doing some research and looking to
see if the library you call, the compiler you use, and everything else
that is associated with this project, actually needs the wrapper?

What Library are you using? What compiler are you using?

All of this stuff needs to be addressed.

You can't simply plug in some code and hope it works.

Ben


0 new messages