[U-Boot] [RFC] initcall mechanism introduction

Hi all,
Linux Kernel has for a long time a well-optimized mechanism for for calling initiallisation code. Import the the same functionnality to U-Boot.
Evenif it will increase a few U-Boot (999 bytes) as show in PATCH 3/3 if we convert the NET_MULTI it will decrease of 2212 bytes at the end
Best Regards, J.

Dear Jean-Christophe PLAGNIOL-VILLARD,
In message 20090523150558.GB26561@game.jcrosoft.org you wrote:
Linux Kernel has for a long time a well-optimized mechanism for for calling initiallisation code. Import the the same functionnality to U-Boot.
Evenif it will increase a few U-Boot (999 bytes) as show in PATCH 3/3 if we convert the NET_MULTI it will decrease of 2212 bytes at the end
What would be the purpose of this in a boot loader?
For Linux iot makes sense to free each and every byte which is no longer needed because applications running can really benefir from it. But in U-Boot? Please check the memory map of the running system. The memory regained will not even be usable by anybody...
What sort of benefit do you expect?
Best regards,
Wolfgang Denk

On 20:19 Sat 23 May , Wolfgang Denk wrote:
Dear Jean-Christophe PLAGNIOL-VILLARD,
In message 20090523150558.GB26561@game.jcrosoft.org you wrote:
Linux Kernel has for a long time a well-optimized mechanism for for calling initiallisation code. Import the the same functionnality to U-Boot.
Evenif it will increase a few U-Boot (999 bytes) as show in PATCH 3/3 if we convert the NET_MULTI it will decrease of 2212 bytes at the end
What would be the purpose of this in a boot loader?
For Linux iot makes sense to free each and every byte which is no longer needed because applications running can really benefir from it. But in U-Boot? Please check the memory map of the running system. The memory regained will not even be usable by anybody...
it you read the patch 1 you will see that I've no which to free it
What sort of benefit do you expect?
simplify the code, reduce the number of ifdef reduce the size of U-Boot etc...
I do have some test and I've gain between 2KiB and more than 10KiB by using this
so yes I think it's great winn
Best Regards, J.

Dear Jean-Christophe PLAGNIOL-VILLARD,
In message 20090524120041.GG26561@game.jcrosoft.org you wrote:
What sort of benefit do you expect?
simplify the code, reduce the number of ifdef reduce the size of U-Boot etc...
How would that reduce the size of the code?
I do have some test and I've gain between 2KiB and more than 10KiB by using this
And, does it still work on all boards?
so yes I think it's great winn
I think you don't understand the complexity yet. One problem we have to solve is to make sure we have a very specific sequence in which the init routines are run. The original idea of the code was that you can #define the init_sequence[] table in an architecture and/or board config file; it's just that nobody implemented that yet.
If you changed the code in this direction, then this might actually make sense.
The Linux way of doing initcalls is useless for U-Boot, as it addres- ses a completely different problem and is based on a completely different memory management model.
Best regards,
Wolfgang Denk

On 16:57 Sun 24 May , Wolfgang Denk wrote:
Dear Jean-Christophe PLAGNIOL-VILLARD,
In message 20090524120041.GG26561@game.jcrosoft.org you wrote:
What sort of benefit do you expect?
simplify the code, reduce the number of ifdef reduce the size of U-Boot etc...
How would that reduce the size of the code?
just as example remove the weak function will reduce the code as show in the patch 3 just re-implement it through it will reduce the size by 2KiB.
I do have some test and I've gain between 2KiB and more than 10KiB by using this
And, does it still work on all boards?
for my current test more api you use more you win as I've not test on all boards I can not certify it
so yes I think it's great winn
I think you don't understand the complexity yet. One problem we have to solve is to make sure we have a very specific sequence in which the init routines are run. The original idea of the code was that you can #define the init_sequence[] table in an architecture and/or board config file; it's just that nobody implemented that yet.
If you changed the code in this direction, then this might actually make sense.
no with initcalls you will be able to do it as it will be a matter of at which state you want to init your code so each arch will be able to specify it and you will be able to also add specific init level on need we are not forced to have the same lds for all arch and/or board too actually I've create only one init.h but we can add a arch specificity
Best Regards, J.

Dear Jean-Christophe PLAGNIOL-VILLARD,
In message 20090524150444.GI26561@game.jcrosoft.org you wrote:
If you changed the code in this direction, then this might actually make sense.
no with initcalls you will be able to do it
May be, but in my opinion at the cost of higher complexity.
I don't see any urgency to move in this direction.
Best regards,
Wolfgang Denk

On Sun, May 24, 2009 at 04:57:25PM +0200, Wolfgang Denk wrote:
I think you don't understand the complexity yet. One problem we have to solve is to make sure we have a very specific sequence in which the init routines are run. The original idea of the code was that you can #define the init_sequence[] table in an architecture and/or board config file; it's just that nobody implemented that yet.
IMHO, it is much better for the information on what needs to be run on init to reside in the file that needs to be called, rather than copied to a bunch of different arch files.
In what practical case would one arch want to run component X before component Y, but another want to run component Y before component X? If component X is always supposed to come before component Y, that can be done with different levels of initcalls, or just by arranging the makefiles appropriately (with a comment warning people not to change it).
If you changed the code in this direction, then this might actually make sense.
The Linux way of doing initcalls is useless for U-Boot, as it addres- ses a completely different problem and is based on a completely different memory management model.
Initcalls are not the same thing as init code/data (other than the coincidence that in Linux, they would typically reside in such sections).
This has nothing to do with memory management.
-Scott

Dear Scott,
in message 20090526210046.GA4669@b07421-ec1.am.freescale.net you wrote:
IMHO, it is much better for the information on what needs to be run on init to reside in the file that needs to be called, rather than copied to a bunch of different arch files.
Then you might end up with another maze of #ifdef's...
In what practical case would one arch want to run component X before component Y, but another want to run component Y before component X? If
Boards are different... see for example "lib_ppc/board.c" - on some boards (BAB7xx and CPC45) we must initialize PCI early, while on some others we cannot initialize it that early.
component X is always supposed to come before component Y, that can be done with different levels of initcalls, or just by arranging the makefiles appropriately (with a comment warning people not to change it).
The problem is that there is no such fix order. It is board dependent.
The Linux way of doing initcalls is useless for U-Boot, as it addres- ses a completely different problem and is based on a completely different memory management model.
Initcalls are not the same thing as init code/data (other than the coincidence that in Linux, they would typically reside in such sections).
This has nothing to do with memory management.
But saving memory was one of j24's arguments?
Best regards,
Wolfgang Denk

On 23:54 Tue 26 May , Wolfgang Denk wrote:
Dear Scott,
in message 20090526210046.GA4669@b07421-ec1.am.freescale.net you wrote:
IMHO, it is much better for the information on what needs to be run on init to reside in the file that needs to be called, rather than copied to a bunch of different arch files.
Then you might end up with another maze of #ifdef's...
In what practical case would one arch want to run component X before component Y, but another want to run component Y before component X? If
Boards are different... see for example "lib_ppc/board.c" - on some boards (BAB7xx and CPC45) we must initialize PCI early, while on some others we cannot initialize it that early.
so it's not really a problem as you can create for thoze two specific boards an early init easly
and just for the understanding why does they need it?
component X is always supposed to come before component Y, that can be done with different levels of initcalls, or just by arranging the makefiles appropriately (with a comment warning people not to change it).
The problem is that there is no such fix order. It is board dependent.
not really the initcall can be easly update via early init or if really need by updating the linker script. Which I think will the last think to do.
The Linux way of doing initcalls is useless for U-Boot, as it addres- ses a completely different problem and is based on a completely different memory management model.
Initcalls are not the same thing as init code/data (other than the coincidence that in Linux, they would typically reside in such sections).
This has nothing to do with memory management.
But saving memory was one of j24's arguments?
It's true but the binary size (u-boot.bin) not the memory management
Best Regards, J.

Dear Jean-Christophe PLAGNIOL-VILLARD,
In message 20090526220736.GB30039@game.jcrosoft.org you wrote:
Boards are different... see for example "lib_ppc/board.c" - on some boards (BAB7xx and CPC45) we must initialize PCI early, while on some others we cannot initialize it that early.
so it's not really a problem as you can create for thoze two specific boards an early init easly
This was just one example - one which I had ready in memory. There are probably more of these.
and just for the understanding why does they need it?
Please see the comments in the code.
But saving memory was one of j24's arguments?
It's true but the binary size (u-boot.bin) not the memory management
So where exactly do you think you can save memory?
Best regards,
Wolfgang Denk

Wolfgang Denk wrote:
Dear Scott,
in message 20090526210046.GA4669@b07421-ec1.am.freescale.net you wrote:
IMHO, it is much better for the information on what needs to be run on init to reside in the file that needs to be called, rather than copied to a bunch of different arch files.
Then you might end up with another maze of #ifdef's...
Only when you have a situation like the BAB7xx/CPC45 (in which case you could ifdef the priority -- or just ifndef the initcall for those boards and handle that special case manually). You wouldn't have ifdefs for just the presence of the thing that needs to be initialized, and it would be only in one place rather than X arch files.
component X is always supposed to come before component Y, that can be done with different levels of initcalls, or just by arranging the makefiles appropriately (with a comment warning people not to change it).
The problem is that there is no such fix order. It is board dependent.
There will be exceptions, but for many things there's just no reason for the board to care (such as the time at which we run relocation fixups or other data structure initialization for things in common/). One shouldn't have to change a bunch of arch files in order to add some new common code that needs init.
This has nothing to do with memory management.
But saving memory was one of j24's arguments?
I assume he meant that the image size was smaller, due to replacing explicit function calls with a table-driven approach.
-Scott

Dear Scott Wood,
In message 4A1C6B48.9050106@freescale.com you wrote:
I assume he meant that the image size was smaller, due to replacing explicit function calls with a table-driven approach.
We already have such a functionpoointer table - problem is that we don't use it everywhere, usually because the init function calls are intermixed with other code.
init_fnc_t *init_sequence[] was the idea that was supposed to solve this very problem, but look at the code...
Best regards,
Wolfgang Denk

Wolfgang Denk wrote:
component X is always supposed to come before component Y, that can be done with different levels of initcalls, or just by arranging the makefiles appropriately (with a comment warning people not to change it).
The problem is that there is no such fix order. It is board dependent.
In other words, what we have right now is the worst of both worlds: - There are shitloads of #ifdefs in the arch code to cope with different board requirements. - There are huge differences between each architecture's init sequence which makes it hard to write generic code elsewhere, and hard to maintain each architecture since the init sequence needs to be changed when new boards add new features, and there's no "standard" way of doing it so the chances of getting it right to begin with are very slim.
Also, the chances of getting this mess cleaned up is very slim since you need to touch all architectures in order to change something.
IMO, introducing a common init sequence for all architectures would be an important step on the way to make this code somewhat maintainable, no matter how messy the initial result ends up being. Or perhaps a better first step would be to clean up the ppc code since it's what new architectures tend to copy, and it's just such an insane mess right now.
Haavard

On Wednesday 27 May 2009 09:52:35 Haavard Skinnemoen wrote:
Wolfgang Denk wrote:
component X is always supposed to come before component Y, that can be done with different levels of initcalls, or just by arranging the makefiles appropriately (with a comment warning people not to change it).
The problem is that there is no such fix order. It is board dependent.
In other words, what we have right now is the worst of both worlds:
- There are shitloads of #ifdefs in the arch code to cope with different board requirements.
ACK. Most of this code was added a long time ago. We wouldn't accept this board specific "hacks" (especially in lib_ppc/board.c) in the common code right now any more.
- There are huge differences between each architecture's init sequence which makes it hard to write generic code elsewhere, and hard to maintain each architecture since the init sequence needs to be changed when new boards add new features, and there's no "standard" way of doing it so the chances of getting it right to begin with are very slim.
Also, the chances of getting this mess cleaned up is very slim since you need to touch all architectures in order to change something.
Yes, I noticed this while moving the malloc initialisation to an earlier stage. It would be really a great improvement if we could consolidate those lib_arch/board.c implementations somehow.
IMO, introducing a common init sequence for all architectures would be an important step on the way to make this code somewhat maintainable, no matter how messy the initial result ends up being. Or perhaps a better first step would be to clean up the ppc code since it's what new architectures tend to copy, and it's just such an insane mess right now.
ACK. Even though I don't have a clue right now how this could be accomplished in practise without breaking some of the (old) board ports.
Nevertheless I think that Jean-Christophe's inicall approach is a good idea which could/should be used here.
Best regards, Stefan
===================================================================== DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office@denx.de =====================================================================

On Wednesday 27 May 2009 04:12:21 Stefan Roese wrote:
ACK. Even though I don't have a clue right now how this could be accomplished in practise without breaking some of the (old) board ports.
i thought current practice was that if no one cared to update board ports and verify they still worked, then they were in effect dead and should be dropped.
i'd also support initcall integration, but in order to have correct initialization order for core aspects, we're still going to need a hardcoded list somewhere -- this is how the kernel works too after all. hopefully this would allow us to unify the board init process into common code though. -mike
participants (6)
-
Haavard Skinnemoen
-
Jean-Christophe PLAGNIOL-VILLARD
-
Mike Frysinger
-
Scott Wood
-
Stefan Roese
-
Wolfgang Denk