[U-Boot-Users] The i386 patch

Hello all
I realize that I threw the figure around yesterdag it was 83kb rather than 38... Todays, cleanup version measure in at 62kb.
I hope you'll like it :)
Wolfgang: This patch touch common code in a few places, nothing to controversion, I hope.
/Daniel

Dear Daniel,
in message 20021113094454.G22221@jupiter.omicron.se you wrote:
I realize that I threw the figure around yesterdag it was 83kb rather than 38... Todays, cleanup version measure in at 62kb.
I hope you'll like it :)
Thanks again for the patch.
Wolfgang: This patch touch common code in a few places, nothing to controversion, I hope.
I tried to merge your patch with the current U-Boot code; I still get a _LOT_ of warnings, and unresolved references from the strings functions, but I think you can pick up here...
A few comments:
* Please, do not add trailing white space to existing code!
* Always make sure to run the MAKEALL script; this catches errors like this one:
- void *to = (void *)ntohl(hdr->ih_load); + void *to = (void *)ntohl(hdr->ih_load));
* Do not use C++ style comments
Comments on specific parts of the patch:
common/cmd_bootm.c:
x86 should _not_ need any special code here. Do you think it is possible to add support for "standard" mkimage format and get rid of your new #ifdef's?
Added with minor modifications:
@@ -145,10 +163,11 @@ SHOW_BOOT_PROGRESS (-2); return 1; } + hdr->ih_hcrc = htonl(checksum); SHOW_BOOT_PROGRESS (3);
I don't understand why this could be needed; omitted.
common/cmd_ide.c:
+#ifdef __PPC__ #define ATA_CURR_BASE(dev) (CFG_ATA_BASE_ADDR+ide_bus_offset[IDE_BUS(dev )]) +#endif ... +#ifdef __PPC__ static void input_swap_data(int dev, ulong *sect_buf, int words); +#endif
Are you sure this is PPC only?
ppcboot/examples/syscall.S:
Are you sure there is only a "ret" needed?
include/asm-arm/string.h: lib_generic/string.c:
Why do you modify ARM and generic files? I want to keep this file as close as possible in sync with standard Linux code.
*** NOT accepted ***
This breaks include/asm-i386/string.h - can you please try to fix this instead?
I've checked the current state in on the U-Boot CVS server. The tag is LABEL_2002_11_18_0115 . Can you please have a look at it and help to clean it up?
TIA!
Best regards,
Wolfgang Denk

Wolfgang,
On 2002.11.18 01:15 Wolfgang Denk wrote:
Comments on specific parts of the patch:
common/cmd_bootm.c:
x86 should _not_ need any special code here. Do you think it is possible to add support for "standard" mkimage format and get rid of your new #ifdef's?
The "standard" mkimage format IS supported, this code add support for Linux images without the mkimage header as well. If you do not need any of the features in the image header the header it slef is just an extra source of problems, for example the load address is bogus for i386 I would like to have an option to ignore it completly for Linux image and always load at a safe place. This is currently what happens if you boot a kernel with out the image header. Or better yet not load the kernel at all if the kernel resides in flash, just give do_bootm_linux() a pointer to where the kernel is located.
Right now do_bootm() loads the kernel from flash and do_bootm_linux() moves it to the correct location.
The fisrt part, setup should be loaded at 0x90000 (size may vary between 2.5k and 32k), the rest of the kernel should be loaded at 0x10000 if it is a zImage or 0x100000 if it is a bzImage.
0xa0000-0xfffff is ROM and memory mapped I/O area, so loading the entire thing at 0x90000 will fail as well.
Added with minor modifications:
@@ -145,10 +163,11 @@ SHOW_BOOT_PROGRESS (-2); return 1; }
SHOW_BOOT_PROGRESS (3);hdr->ih_hcrc = htonl(checksum);
I don't understand why this could be needed; omitted.
OK, I saw that it was referenced below in the function, but it seems to be when the ramdisk-image gets loaded, so that would be another header.
common/cmd_ide.c: +#ifdef __PPC__ Are you sure this is PPC only?
No, I thought that ide was only used by ppc before, but I se now that IDE is used by the ARM as well. Should perhaps be #ifdef __BIG_ENDIAN ?
ppcboot/examples/syscall.S:
Are you sure there is only a "ret" needed?
Its a place holder, syscalls are not functional yet. I think it will be a problem that printf is defined as a syscall because it is a variable argument list function.
How do I know how much of the stack to copy when I enter the firmware?
/Daniel

Dear Daniel,
in message 20021118113139.E892@jupiter.omicron.se you wrote:
x86 should _not_ need any special code here. Do you think it is possible to add support for "standard" mkimage format and get rid of your new #ifdef's?
The "standard" mkimage format IS supported, this code add support for Linux images without the mkimage header as well.
I see.
Or better yet not load the kernel at all if the kernel resides in flash, just give do_bootm_linux() a pointer to where the kernel is located.
Right. This is something which I probably should fix on PPC, too (fixed on ARM some time ago).
common/cmd_ide.c: +#ifdef __PPC__ Are you sure this is PPC only?
No, I thought that ide was only used by ppc before, but I se now that IDE is used by the ARM as well. Should perhaps be #ifdef __BIG_ENDIAN ?
But ARM is little endian!
ppcboot/examples/syscall.S:
Are you sure there is only a "ret" needed?
Its a place holder, syscalls are not functional yet.
Then we should rather have a #warning similar to the current styate in ARM.
I think it will be a problem that printf is defined as a syscall because it is a variable argument list function.
How do I know how much of the stack to copy when I enter the firmware?
What do you mean with "stack to copy"? You are running in the U-Boot environment, accessing the U-Boot stack directly. No need to copy anything...
Best regards,
Wolfgang Denk

Am Dienstag, 19. November 2002 22:19 schrieb Wolfgang Denk:
I think it will be a problem that printf is defined as a syscall because it is a variable argument list function.
How do I know how much of the stack to copy when I enter the firmware?
What do you mean with "stack to copy"?
The standard method for the x86 to implement a syscall is through a "gate", which is also a mechanism to switch to a higher protection level. Since caller and callee run at different protection levels, they use different stacks and since the x86 passes arguments on the stack, it is possible to specify (in the corresponding gate structure) the amount of bytes to be copied from the caller's stack to the callee's stack.
You are running in the U-Boot environment, accessing the U-Boot stack directly. No need to copy anything...
Does that mean that the caller always runs at the same protection level as U-Boot?
If so, then I think that a syscall mechanism for the x86 through gates would be overkill. But then, OTOH, why use syscalls at all ? A simple jump table could do the same thing, and do it portably.
Rob
---------------------------------------------------------------- Robert Kaiser email: rkaiser@sysgo.de SYSGO AG Am Pfaffenstein 14 phone: (49) 6136 9948-762 D-55270 Klein-Winternheim / Germany fax: (49) 6136 9948-10

In message 200211201114.gAKBEss01326@dagobert.svc.sysgo.de you wrote:
What do you mean with "stack to copy"?
The standard method for the x86 to implement a syscall is through a "gate", which is also a mechanism to switch to a higher protection level. Since caller and callee run at different protection levels, they use
OK, understood.
But this is not what U-Boot needs.
Does that mean that the caller always runs at the same protection level as U-Boot?
Right.
If so, then I think that a syscall mechanism for the x86 through gates would be overkill. But then, OTOH, why use syscalls at all ? A simple jump table could do the same thing, and do it portably.
You may remember that we used a jump table attached to the global data in early versions of PPCBoot. I didn't like this. The nice thing about the syscall trap on PPC is that you can easily put a "jump table" at a well-known location, so that a standalone application can access certain services (those explicitely exported by U-Boot using the syscall interface) without depending on a special software version.
I have to admit that I did not think about other architectures at the time we implemented this.
Best regards,
Wolfgang Denk

On 2002.11.20 15:06 Wolfgang Denk wrote:
In message 200211201114.gAKBEss01326@dagobert.svc.sysgo.de you wrote:
You may remember that we used a jump table attached to the global data in early versions of PPCBoot. I didn't like this. The nice thing about the syscall trap on PPC is that you can easily put a "jump table" at a well-known location, so that a standalone application can access certain services (those explicitely exported by U-Boot using the syscall interface) without depending on a special software version.
I have to admit that I did not think about other architectures at the time we implemented this.
The i386 can do indirect calls on the ebp register. So we could let the application know the location of the syscall table by providing it in a register on entry. The applications initialization code can then store it in a suitable location (called syscall_table below).
The syscall would than be done like this:
movl $SYSCALL_NR, %eax movl syscall_table, %ebp shll $2, %eax addl %eax, %ebp call *%ebp ret
/Daniel

Am Mittwoch, 20. November 2002 15:18 schrieb Daniel Engström:
The i386 can do indirect calls on the ebp register. So we could let the application know the location of the syscall table by providing it in a register on entry. The applications initialization code can then store it in a suitable location (called syscall_table below).
The syscall would than be done like this:
movl $SYSCALL_NR, %eax movl syscall_table, %ebp shll $2, %eax addl %eax, %ebp call *%ebp ret
Exactly, except that I would do it in C:
---------------------------- cut here ---------------------------- /* ** The U-Boot's anchor :-) ** This is an absolute address that is otherwise unused. ** U-boot sets it to contain the address of the syscall ** jumptable, so clients can make calls into U-boot. */ #define UBOOT_ANCHOR 0x.....
struct syscall_jmptbl { int (*j_mon_getc)(void); int (*j_mon_tstc)(void); void (*j_mon_putc)(const char); void (*j_mon_puts)(const char*); void (*j_mon_printf)(const char* fmt, ...); void (*j_mon_install_hdlr)(int, interrupt_handler_t*, void*); void (*j_mon_free_hdlr)(int); void *(*j_mon_malloc)(size_t); void (*j_mon_free)(void*); void (*j_mon_udelay)(unsigned long); unsigned long (*j_mon_get_timer)(unsigned long); };
... in U-BOOT startup:
static struct syscall_jmptbl jmptable;
...
jmptable.j_mon_getc = mon_getc; jmptable.j_mon_tstc = mon_tstc; jmptable.j_mon_putc = mon_putc; jmptable.j_mon_puts = mon_puts; jmptable.j_mon_printf = mon_printf; jmptable.j_mon_install_hdlr = mon_install_hdlr; jmptable.j_mon_free_hdlr = mon_free_hdlr; jmptable.j_mon_malloc = mon_malloc; jmptable.j_mon_free = mon_free; jmptable.j_mon_udelay = mon_udelay; jmptable.j_mon_get_timer= mon_get_timer;
/* publish location of jump table */ *((struct syscall_jmptbl**)UBOOT_ANCHOR) = &jmptable;
....
in client:
struct syscall_jmptbl *tbl;
tbl = *((struct syscall_jmptbl**)UBOOT_ANCHOR);
tbl->j_mon_printf("Hello\n");
... ---------------------------- cut here ----------------------------
This would essentially do the same thing, but it should work on all platforms.
Rob
---------------------------------------------------------------- Robert Kaiser email: rkaiser@sysgo.de SYSGO AG Am Pfaffenstein 14 phone: (49) 6136 9948-762 D-55270 Klein-Winternheim / Germany fax: (49) 6136 9948-10

Am Mittwoch, 20. November 2002 15:06 schrieben Sie:
In message 200211201114.gAKBEss01326@dagobert.svc.sysgo.de you wrote:
[explanation of x86 gate mechanism ..]
But this is not what U-Boot needs.
I thought so :-)
You may remember that we used a jump table attached to the global data in early versions of PPCBoot. I didn't like this. The nice thing about the syscall trap on PPC is that you can easily put a "jump table" at a well-known location, so that a standalone application can access certain services (those explicitely exported by U-Boot using the syscall interface) without depending on a special software version.
So, essentially, the syscall mechanism in U-Boot/PPC is just a jump table at a well known location, where that location is defined by the architecture, right ?
This surely makes sense, but I'm not sure wether it should be adopted as a model for the other architectures.
Why not do it as the good old OS-9 or pSOS did: identify one absolute address that is otherwise unused (every architecture has this in some form: an unused trap vector, unused word in space reserved for first level exception handler, etc.). In that location, have U-boot publish the address of the jump table at startup time (by storing a pointer to it). This is actually no different from the trap mechanism used by the PPC, except that the "well-known location" is defined by convention rather than by the hardware. And this could be done portably.
Rob
---------------------------------------------------------------- Robert Kaiser email: rkaiser@sysgo.de SYSGO AG Am Pfaffenstein 14 phone: (49) 6136 9948-762 D-55270 Klein-Winternheim / Germany fax: (49) 6136 9948-10
participants (3)
-
Daniel Engström
-
Robert Kaiser
-
Wolfgang Denk