Hello, I have the following problem:
* I have my own bootloader, and when I try to use some small printf function, something goes wrong with va_list and va_arg. It seems like the wrong memory addresses are used. Anyone has ever this kind of problem? My bootloader activates the A20 line, enters pmode, and some other initialization (no IDTs, no Memory initialization).
Thanks
Problem with va_list in my bootloader
Re:Problem with va_list in my bootloader
can you post the code here it makes it easier to find the problem as the source of your whoes can be various things.
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Problem with va_list in my bootloader
two things:
- common mistakes can make strings unavailable from your code. Have you checked you could print strings _without_ va_list. e.g. can you come with a working "puts("Hello, World") ?
- va_args may have unobvious ways to handle attributes that have size differing from sizeof(int). Especially, bytes and halfwords take 32bits on the stack, and not 8 or 16 bits. make sure your code handle this properly.
If this still leaves you clueless, please provide us a test case of what's going wrong (e.g. do kprintf("hello") work but not "kprintf("hello %s", world) ? or does only "version %d.%d.%d", v,e,r cause you trouble ?
- common mistakes can make strings unavailable from your code. Have you checked you could print strings _without_ va_list. e.g. can you come with a working "puts("Hello, World") ?
- va_args may have unobvious ways to handle attributes that have size differing from sizeof(int). Especially, bytes and halfwords take 32bits on the stack, and not 8 or 16 bits. make sure your code handle this properly.
If this still leaves you clueless, please provide us a test case of what's going wrong (e.g. do kprintf("hello") work but not "kprintf("hello %s", world) ? or does only "version %d.%d.%d", v,e,r cause you trouble ?
Re:Problem with va_list in my bootloader
I can print text on the screen via the putstr function that I've programmed. But when I try to use some printf funcion with va_list, I can not even do a simple printf("text"). The function works fine on Linux, but in my bootloader not. The sprinf("text") doesn't work either. I've checked the function and it's alright. The problem is the va_list. I'm going to put some code in this page, but the problem is that my bootloader occupy 50 kb of code. If I don't get it work, I'm going to zip my bootloader in put in the forum.
Thanks a lot.
Thanks a lot.
Re:Problem with va_list in my bootloader
Hmm... you say that the putstr function you wrote works correctly, but when you use "some printf function" it breaks.
Three questions, as I have a nagging suspicion what might be the problem here:
If the answer is not "Linux", we'll need to see the code. Not necessarily your boot loader, but your printf() function (including the <stdio.h> header), and your <stdargs.h>.
Three questions, as I have a nagging suspicion what might be the problem here:
- where did the printf() function you are using come from?
- where did the <stdio.h> header file you are including to have printf() declared come from?
- where did the <stdargs.h> header file you are including to have va_list et al. defined come from?
If the answer is not "Linux", we'll need to see the code. Not necessarily your boot loader, but your printf() function (including the <stdio.h> header), and your <stdargs.h>.
Every good solution is obvious once you've found it.
Re:Problem with va_list in my bootloader
* I programmed a small version of printf by myself
* I don't use stdio.h, because I don't need it
* I use this stdarg.h
#ifndef __STDARG_H
#define __STDARG_H
#define STACKITEM int
typedef unsigned char *va_list;
#define VA_SIZE(TYPE) \
((sizeof(TYPE) + sizeof(STACKITEM) - 1) \
& ~(sizeof(STACKITEM) - 1))
#define va_start(AP, LASTARG) \
(AP=((va_list)&(LASTARG) + VA_SIZE(LASTARG)))
#define va_end(AP) /* nothing */
#define va_arg(AP, TYPE) \
(AP += VA_SIZE(TYPE), *((TYPE *)(AP - VA_SIZE(TYPE))))
#endif
* I don't use stdio.h, because I don't need it
* I use this stdarg.h
#ifndef __STDARG_H
#define __STDARG_H
#define STACKITEM int
typedef unsigned char *va_list;
#define VA_SIZE(TYPE) \
((sizeof(TYPE) + sizeof(STACKITEM) - 1) \
& ~(sizeof(STACKITEM) - 1))
#define va_start(AP, LASTARG) \
(AP=((va_list)&(LASTARG) + VA_SIZE(LASTARG)))
#define va_end(AP) /* nothing */
#define va_arg(AP, TYPE) \
(AP += VA_SIZE(TYPE), *((TYPE *)(AP - VA_SIZE(TYPE))))
#endif
Re:Problem with va_list in my bootloader
Hm... that code seems to be functionally identical to what I have in the PDCLib (courtesy to Michael Moody who contributed the code). Means, your stdargs.h should work. Although I haven't stress-tested PDCLib's stdargs.h yet, either, it seemed to work for Michael.
It would really be helpful if we could see the code for your printf() and your putstr().
How do you know?I've checked the function and it's alright. The problem is the va_list.
It would really be helpful if we could see the code for your printf() and your putstr().
Every good solution is obvious once you've found it.
Re:Problem with va_list in my bootloader
Ok, I fixed the problem. Some strange behaviors occurs in gcc when the segment registers points to selectors with different base.
Thanks all for your help.
Thanks all for your help.
Re:Problem with va_list in my bootloader
Ah, that one... well, it's true (and documented) that GCC does support a flat memory model only.panchin wrote: Some strange behaviors occurs in gcc when the segment registers points to selectors with different base.
Every good solution is obvious once you've found it.