Page 1 of 2
Understanding intcall in linux kernel
Posted: Thu Feb 23, 2017 10:04 am
by dream21
I am trying to understand the code for
intcall which is used for generating bios interrupt for displaying text on the screen. Can anybody please help me understanding this code.
https://github.com/torvalds/linux/blob/ ... bioscall.S
I have read the mailing list on this topic
Glove Box for BIOS calls
. Linus stated that that the code introduces a lot more complexities as most of the BIOSses available are buggy as the code will run 99% of the time but break unexpectedly in other cases.
Re: Understanding intcall in linux kernel
Posted: Thu Feb 23, 2017 10:45 am
by Brendan
Hi,
dream21 wrote:I am trying to understand the code for
intcall which is used for generating bios interrupt for displaying text on the screen. Can anybody please help me understanding this code.
https://github.com/torvalds/linux/blob/ ... bioscall.S
I have read the mailing list on this topic
Glove Box for BIOS calls
. Linus stated that that the code introduces a lot more complexities as most of the BIOSses available are buggy as the code will run 99% of the time but break unexpectedly in other cases.
It's a hideously retarded, ugly, inefficient and over-engineered general purpose way to make it easier for (16-bit) C code to call a BIOS function "more safely".
If you want to do it right; briefly consider using an inline assembly macro for each BIOS function you use, but then shift it all out of the kernel (and put it in a boot loader where it belongs) instead of doing that.
Cheers,
Brendan
Re: Understanding intcall in linux kernel
Posted: Thu Feb 23, 2017 11:31 am
by dream21
If you want to do it right; briefly consider using an inline assembly macro for each BIOS function you use, but then shift it all out of the kernel (and put it in a boot loader where it belongs) instead of doing that.
Yes, I think that would be better as it adds unnecessary complexity to the kernel.
Re: Understanding intcall in linux kernel
Posted: Sat Feb 25, 2017 9:43 pm
by dream21
If someone comes here looking for an explanation then I found an excellent Chinese blog
http://blog.csdn.net/sinat_32662325/art ... s/50428551
Re: Understanding intcall in linux kernel
Posted: Sun Feb 26, 2017 10:41 am
by Schol-R-LEA
dream21 wrote:I am trying to understand the code for intcall which is used for generating bios interrupt for displaying text on the screen. Can anybody please help me understanding this code.
If you don't mind me asking, why are you looking into that particular call? If you are trying to understand how to use it in Linux itself, then the thread should be moved to General Programming.
On the other hand, if you are looking to implement the same thing in your OS, you need to stop and reconsider the matter. Unless your actual goal is to support legacy 16-bit MS-DOS code (yeah, good luck with that), you
don't want to do this. Using BIOS calls for console handling in a 32-bit OS is going to be more trouble than it is worth, no matter how well or poorly you implement it.
Even in 16-bit code, the BIOS is generally a poor fit; most MS-DOS programs that needed more than the most basic stream-oriented text output bypassed them, and every MS-DOS compiler of note avoided it in their own console libraries even for stream I/O. MS-DOS itself avoided the BIOS for many things it nominally could have been be used for, because even a good implementation of the BIOS was worse than a lousy, generic implementation of the same code which used interrupts instead of polling.
While it takes a little effort upfront, the truth is that the BIOS console routines are going to be a lot
more work to deal with down the road, and working directly with the text buffers is actually the easier option.
Re: Understanding intcall in linux kernel
Posted: Sun Feb 26, 2017 12:26 pm
by Korona
That code is not used in modern Linux installations (i.e. when you load the kernel via GRUB's "linux" command). It is only used alongside 16-bit boot loaders.
Re: Understanding intcall in linux kernel
Posted: Sun Feb 26, 2017 6:16 pm
by x64dev
You don't need the BIOS to output text to the screen.
I avoided this by writing text output routines that tracked the current cursor x & y co-ordinates and using this to calculate the offset from linear address 0xb8000 (the text mode graphics buffer). Once 25-lines have been output (in 80x25 mode), I "scroll" the text up by moving row 1-24 up to row 0-23 and then zero out row 24 (0 based).
It's fast and works in 16-bit, 32-bit and 64-bit mode. Although in 16-bit mode you'll need to use es=0xb800. I don't have the code with me currently, but I can try to share it when I'm back home.
Re: Understanding intcall in linux kernel
Posted: Thu Mar 02, 2017 3:18 am
by dream21
x64dev wrote:It's fast and works in 16-bit, 32-bit and 64-bit mode. Although in 16-bit mode you'll need to use es=0xb800. I don't have the code with me currently, but I can try to share it when I'm back home.
I would surely like to see it!
Re: Understanding intcall in linux kernel
Posted: Thu Mar 02, 2017 8:56 pm
by Schol-R-LEA
You might want to check the wiki page on
Text UI,
Text Mode Cursor, while you're waiting, if you haven't already done so. The rest of the Video category would be a place to mine of information in general, actually (there are links to the categories at the bottom of any categorized page, including both of those), though much of those are focused on more advanced topics, especially those regarding non-text video modes.
Re: Understanding intcall in linux kernel
Posted: Fri Mar 03, 2017 7:55 pm
by dream21
My overall aim was not only to use interrupts to display text on screen but also to use interrupts like 0x13 and 0x15. What
intcall provides is we can save the state of the registers using "C" syntax but if we don't want to use ugly
intcall, code will be large (I will not say complicated as we all understand assembly the best
).
Re: Understanding intcall in linux kernel
Posted: Fri Mar 03, 2017 8:51 pm
by Schol-R-LEA
...Wait, what?
You might want to use INT 0x15, to probe the APM settings and memory, yes, but not from p-mode - those are things done at boot-up, in real mode, by your boot loader. If you are writing your own loader, then you would need them, but not through intcall. More likely, you will just get them from GRUB, which probably gets it from UEFI if it is running on even moderately recent hardware.
You most definitely do not want to use INT 0x13 after your kernel is loaded. The drive interfaces are actually not much harder to use than the BIOS tools are, and I can promise you that you'll regret trying to use the BIOS for drive interfacing in a protected mode OS - or a real mode one, for that matter. HD and FD drivers really benefit from the use of interrupt processing, and the BIOS only works through polling - and slowly, at that.
The BIOS is not your friend. It is a millstone which you need to get off from around your neck at the earliest opportunity. Even as a novice OS developer, the trouble you will have trying to get the BIOS to run from protected mode is much greater than the work of simply writing the protected-mode drivers yourself.
Re: Understanding intcall in linux kernel
Posted: Fri Mar 03, 2017 11:45 pm
by dream21
I think I have a weak understanding of how Linux kernel sets up things. First, it defines its structure according to the boot protocol, some values gets filled by the grub and other by cmdline parameters. Then there is a long jump to the main function which is not in protected mode
Code: Select all
void main(void)
{
/* First, copy the boot header into the "zeropage" */
copy_boot_params();
/* Initialize the early-boot console */
console_init();
if (cmdline_find_option_bool("debug"))
puts("early console in setup code\n");
/* End of heap check */
init_heap();
/* Make sure we have all the proper CPU support */
if (validate_cpu()) {
puts("Unable to boot - please use a kernel appropriate "
"for your CPU.\n");
die();
}
/* Tell the BIOS what CPU mode we intend to run in. */
set_bios_mode();
/* Detect memory layout */
detect_memory();
/* Set keyboard repeat rate (why?) and query the lock flags */
keyboard_init();
/* Query Intel SpeedStep (IST) information */
query_ist();
/* Query APM information */
#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
query_apm_bios();
#endif
/* Query EDD information */
#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
query_edd();
#endif
/* Set the video mode */
set_video();
/* Do the last things and invoke protected mode */
go_to_protected_mode();
}
The protected mode is setup at the end but it starts using C in real mode?
Re: Understanding intcall in linux kernel
Posted: Sat Mar 04, 2017 10:10 am
by Schol-R-LEA
It's more that a provision for it is there, if the system is using a loader that doesn't switch to p-mode before handing off control, but the C code has to be compiled by a separate 16-compiler (since GCC doesn't support real mode at all for a number of reasons). I believe that the one used at one point was
BCC, but I don't know if that's still the case. The loader has to be configured to call this code first, which then does the prep to call the kernel proper.
A loader that handles the p-mode switch for you, such as GRUB, will do all the BIOS hardware probing for you and put the data into a package to pass to the kernel. Such a loader would also have to be configured to bypass the default 16-bit boot-up and pass control to the kernel directly.
So the code you are looking at here is only really there for an edge case, and is not the start-up used by Linux on most systems today. The x86/boot directory, with all the 16-bit startup code, is basically Linux's appendix, important at one time but now sort of just hanging around there in a reduced form because there's no reason to eliminate it even though it isn't really needed anymore.
Re: Understanding intcall in linux kernel
Posted: Sun Mar 05, 2017 1:46 pm
by Korona
Schol-R-LEA wrote:It's more that a provision for it is there, if the system is using a loader that doesn't switch to p-mode before handing off control, but the C code has to be compiled by a separate 16-compiler (since GCC doesn't support real mode at all for a number of reasons). I believe that the one used at one point was
BCC, but I don't know if that's still the case. The loader has to be configured to call this code first, which then does the prep to call the kernel proper.
They are generating 32-bit code with GCC and emit ".code16" via inline assembly. This works if you ensure that your code and data segments are small enough to not require segment register handling.Q
Re: Understanding intcall in linux kernel
Posted: Sun Mar 05, 2017 10:10 pm
by dream21
Schol-R-LEA wrote:
So the code you are looking at here is only really there for an edge case, and is not the start-up used by Linux on most systems today. The x86/boot directory, with all the 16-bit startup code, is basically Linux's appendix, important at one time but now sort of just hanging around there in a reduced form because there's no reason to eliminate it even though it isn't really needed anymore.
So that means that we cannot build a minimal boot environment using that code?