Previously the romvec stdin/stdout ihandles were configured so that they were set to the current stdin and stdout paths at initialisation time. Unfortunately as stdin/stdout can be changed with the input and output words, they can end up pointing to invalid ihandles causing a crash when trying to output to the console.
Fix this by pointing the romvec structure to the address of the stdin/stdout variables so that they are always in sync. Similarly we also resolve the text path stdin/stdout variables at boot time to ensure that they will never be stale.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/arch/sparc32/boot.c | 15 +++++++++++++-- openbios-devel/arch/sparc32/romvec.c | 14 +++++--------- 2 files changed, 18 insertions(+), 11 deletions(-)
diff --git a/openbios-devel/arch/sparc32/boot.c b/openbios-devel/arch/sparc32/boot.c index 9e49984..20d3289 100644 --- a/openbios-devel/arch/sparc32/boot.c +++ b/openbios-devel/arch/sparc32/boot.c @@ -23,7 +23,7 @@ const void *romvec; void go(void) { ucell address, type, size; - int image_retval = 0, proplen, target, device; + int image_retval = 0, intprop, proplen, target, device; phandle_t chosen; char *prop, *id, *name; static char bootpathbuf[128], bootargsbuf[128], buf[128]; @@ -40,8 +40,19 @@ void go(void) needs to be set up to pass certain parameters using a C struct. Hence this section extracts the relevant boot information and places it in obp_arg. */ - /* Get the name of the selected boot device, along with the device and unit number */ + /* Get the stdin and stdout paths */ chosen = find_dev("/chosen"); + intprop = get_int_property(chosen, "stdin", &proplen); + PUSH(intprop); + fword("get-instance-path"); + ((struct linux_romvec *)romvec)->pv_stdin = pop_fstr_copy(); + + intprop = get_int_property(chosen, "stdout", &proplen); + PUSH(intprop); + fword("get-instance-path"); + ((struct linux_romvec *)romvec)->pv_stdout = pop_fstr_copy(); + + /* Get the name of the selected boot device, along with the device and unit number */ prop = get_property(chosen, "bootpath", &proplen); strncpy(bootpathbuf, prop, proplen); prop = get_property(chosen, "bootargs", &proplen); diff --git a/openbios-devel/arch/sparc32/romvec.c b/openbios-devel/arch/sparc32/romvec.c index 2e154c1..b1083c3 100644 --- a/openbios-devel/arch/sparc32/romvec.c +++ b/openbios-devel/arch/sparc32/romvec.c @@ -25,7 +25,6 @@ #endif
char obp_stdin, obp_stdout; -static int obp_fd_stdin, obp_fd_stdout; const char *obp_stdin_path, *obp_stdout_path;
struct linux_arguments_v0 obp_arg; @@ -498,15 +497,12 @@ init_openprom(void) romvec0.pv_v2bootargs.bootpath = &bootpath;
romvec0.pv_v2bootargs.bootargs = &obp_arg.argv[1]; - romvec0.pv_v2bootargs.fd_stdin = &obp_fd_stdin; - romvec0.pv_v2bootargs.fd_stdout = &obp_fd_stdout;
- push_str(obp_stdin_path); - fword("open-dev"); - obp_fd_stdin = POP(); - push_str(obp_stdout_path); - fword("open-dev"); - obp_fd_stdout = POP(); + /* Point fd_stdin/fd_stdout to the Forth stdin/stdout variables */ + fword("stdin"); + romvec0.pv_v2bootargs.fd_stdin = cell2pointer(POP()); + fword("stdout"); + romvec0.pv_v2bootargs.fd_stdout = cell2pointer(POP());
romvec0.v3_memalloc = obp_memalloc_handler;