English Amiga Board


Go Back   English Amiga Board > Coders > Coders. System

 
 
Thread Tools
Old 04 June 2022, 14:00   #1
hop
Registered User
 
Join Date: Apr 2019
Location: UK
Posts: 172
Bootblock completion function

I've written a bootblock trackdisk hunk loader and it's all working fine. Currently to execute the loaded code, the address of the entry point is loaded into A0 and jumped to:

Code:
; BB Header
	<load hunk file>
	<clear caches>
	movea.l rootHunks(pc),a0  ; first root hunk memory
	jmp (a0)
...
rootHunks:	ds.l	MAX_ROOT_HUNKS	; table of pointers (32-bit addresses, longwords)
I thought this was OK, but I might as well do it properly and let the system free the bootblock memory:

3. The boot code returns with results in both D0 and A0.

a) Non-zero D0 indicates boot failure. The recoverable alert
AN_BootError is presented before continuing.

b) Zero D0 indicates A0 contains a pointer to the function to
complete the boot. This completion function is chained to with
SysBase in A6 after the strap module frees all its resources.
It is usually the dos.library initialization function, from the
dos.library resident tag. Return from this function is
identical to return from the strap module itself.


http://amigadev.elowar.com/read/ADCD.../node007D.html

Code:
; BB Header
	<load hunk file>
	<clear caches>
	movea.l rootHunks(pc),a0	; first root hunk memory
	moveq #0,d0
	rts
...
rootHunks:	ds.l	MAX_ROOT_HUNKS	; table of pointers (32-bit addresses, longwords)
However this doesn't seem to work and end up with a Guru invalid instruction.

Perhaps I have misunderstood this, or there is a bug in my implementation.
hop is offline  
Old 04 June 2022, 18:07   #2
paraj
Registered User
 
paraj's Avatar
 
Join Date: Feb 2017
Location: Denmark
Posts: 1,098
At what address does it fail? Is your code called? (put a breakpoint on the first instruction
of the loaded code). Check that the stack pointer is the same when you return as it was on entry.

KS1.3 (and probably the others) do very little between returning from the BB code and doing literally "JMP (A0)" itself, just cleanup and adding a DF0 DosNode.

Maybe you're corrupting some OS data structures or use too much stack for yourself (not sure if that can be an issue though).
paraj is offline  
Old 04 June 2022, 18:36   #3
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
Quote:
Originally Posted by hop View Post
b) Zero D0 indicates A0 contains a pointer to the function to complete the boot.
This is important. The OS does not expect any function pointer in
A0
, but a function which initialises dos.library, so the system can complete the boot. If you return from the boot block you must have called
FindResident("dos.library")
and return a pointer to its init function. Nothing else.

I'm sure Thomas can provide you with more details.
phx is offline  
Old 04 June 2022, 19:03   #4
paraj
Registered User
 
paraj's Avatar
 
Join Date: Feb 2017
Location: Denmark
Posts: 1,098
Quote:
Originally Posted by phx View Post
This is important. The OS does not expect any function pointer in
A0
, but a function which initialises dos.library, so the system can complete the boot. If you return from the boot block you must have called
FindResident("dos.library")
and return a pointer to its init function. Nothing else.

I'm sure Thomas can provide you with more details.

If for whatever reason the code is fine with just using exec, graphics and trackdevice shouldn't it still be fine (like OPs code, since it works without returning)?


Made a quick test boot block, that allocates some memory, copies some fixed code there and it runs just fine (and can call exec).


The linked doc even says "It is usually the dos.library initialization function" indicating that it could be something else.
paraj is offline  
Old 04 June 2022, 20:05   #5
ross
Defendit numerus
 
ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
You can examine my addchip bootblock: https://eab.abime.net/showpost.php?p...3&postcount=25
ross is offline  
Old 05 June 2022, 01:29   #6
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
Quote:
Originally Posted by paraj View Post
If for whatever reason the code is fine with just using exec, graphics and trackdevice shouldn't it still be fine (like OPs code, since it works without returning)?
It would certainly be fine, when DOS is initialised in the end. But hop's last example just shows that the boot block returns to the OS with his private function in a0. It is unknown if this routine does the DOS-initialisation itself, like in Ross' example. I assumed it didn't.

Quote:
The linked doc even says "It is usually the dos.library initialization function" indicating that it could be something else.
It was probably the plan to support other disk operating systems. Don't know if it really works.

Only hop can answer what his code-hunk is really doing. Maybe it just returns with
RTS
, which could explain the Guru.
phx is offline  
Old 05 June 2022, 02:12   #7
Galahad/FLT
Going nowhere
 
Galahad/FLT's Avatar
 
Join Date: Oct 2001
Location: United Kingdom
Age: 50
Posts: 8,986
Quote:
Originally Posted by phx View Post
It would certainly be fine, when DOS is initialised in the end. But hop's last example just shows that the boot block returns to the OS with his private function in a0. It is unknown if this routine does the DOS-initialisation itself, like in Ross' example. I assumed it didn't.

It was probably the plan to support other disk operating systems. Don't know if it really works.

Only hop can answer what his code-hunk is really doing. Maybe it just returns with
RTS
, which could explain the Guru.
His code hunk likely still has its AmigaDOS executable stuff appended to the front, so is his code hunk PC relative? If not PC relative has the code been properly relocated?

If he hasn't done that, he's not bypassing the first 32 bytes which can sometimes be interpreted as code when its not.
Galahad/FLT is offline  
Old 05 June 2022, 10:20   #8
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,215
Quote:
Originally Posted by phx View Post
This is important. The OS does not expect any function pointer in
A0
, but a function which initialises dos.library, so the system can complete the boot. If you return from the boot block you must have called
FindResident("dos.library")
and return a pointer to its init function. Nothing else.

I'm sure Thomas can provide you with more details.

Well, it works as stated. If your code returns with d0=0, then a0 is assumed to be a function pointer to a function that completes the boot. The standard os boot block continues with the dos.library init function, but it can be any other function as well. This other function is not "expected to return" to anything, it just does the booting and takes over the system. If the function returns, then the ROM code runs into WarmCapture (in exec), and then just stops the system with a colored background.



Note, however, that if that other function is in your boot block, you have a problem because the memory of your boot block is released after you return, and thus the Os jumps into the wild. IOWs, you need to be sure that this other function runs on its own memory, so you have to allocate memory on your own, and copy or load this other function to this place.



The reason for this indirection was that CBM envisioned that some other Dos than Tripos could be used on top of AmigaOs, thus the dos.library is just one potential candidate DOS a boot block could initiate.


The dos.library itself initializes itself, then initializes remaining ROM modules, and then the situation differs a bit: Under 3.1.4 and below, it starts a shell (the Initial CLI), then terminates. The initial CLI then initializes the remaining system as part of its InitCLI() function (which is an internal function in the dos.library).


In 3.2, this is somewhat different. Dos Init there starts System-startup, then termintes itself, and System-startup initializes the rest of the system, and as last step, it lauches the initial CLI and then quits. It's like the "Init" process of of Unix that takes care of mounting devices and triggering the initial shell.
Thomas Richter is offline  
Old 05 June 2022, 10:33   #9
hop
Registered User
 
Join Date: Apr 2019
Location: UK
Posts: 172
Thanks for all the responses.

Please find attached loader and loadfile source to provide more context (EDIT: To assemble, requires latest build of vasm to support ASSERT directive)

My loadfile(s) are not initialising the dos library. I hope this is not a requirement. I was under the impression that the boot process was designed to be flexible, providing the open IO trackdisk request and calling an arbitrary function at the end of it. I didn't realise the Completion Handler had to init DOS. Seems very restrictive. If this is the case, then I guess a JMP is the only option and the bootblock memory can never be reclaimed, unless the system is completely taken-over.

It doesn't look like even my simple artificial loadfile is being called.

Stack is not being corrupted.

I have confirmed that the loadfile is being correctly relocated.

I have been testing under stock A500 Kickstart 1.3.
Attached Files
File Type: 7z hunk_loader_bootblock_trackdisk.7z (10.0 KB, 23 views)

Last edited by hop; 05 June 2022 at 10:44.
hop is offline  
Old 05 June 2022, 10:38   #10
hop
Registered User
 
Join Date: Apr 2019
Location: UK
Posts: 172
Quote:
Originally Posted by Thomas Richter View Post
Well, it works as stated. If your code returns with d0=0, then a0 is assumed to be a function pointer to a function that completes the boot. The standard os boot block continues with the dos.library init function, but it can be any other function as well.
Thanks. This is very reassuring and good design! There must be another issue with my loader.


Quote:
Originally Posted by Thomas Richter View Post
you need to be sure that this other function runs on its own memory, so you have to allocate memory on your own, and copy or load this other function to this place.
This is the case. Hunk memory is AllocMemed and relocated as appropriate.
hop is offline  
Old 05 June 2022, 10:40   #11
hop
Registered User
 
Join Date: Apr 2019
Location: UK
Posts: 172
Quote:
Originally Posted by Galahad/FLT View Post
His code hunk likely still has its AmigaDOS executable stuff appended to the front, so is his code hunk PC relative? If not PC relative has the code been properly relocated?

If he hasn't done that, he's not bypassing the first 32 bytes which can sometimes be interpreted as code when its not.
The hunk loadfile is parsed properly, starting with the header, so I'm pretty sure it all works as it should. In fact the loader works just fine if the entry point is JMPed to, rather than in A0 after RTS.
hop is offline  
Old 05 June 2022, 10:48   #12
hop
Registered User
 
Join Date: Apr 2019
Location: UK
Posts: 172
Quote:
Originally Posted by ross View Post
You can examine my addchip bootblock: https://eab.abime.net/showpost.php?p...3&postcount=25
Thanks for this. It looks like preserving all registers might have fixed it!

Code:
; BB Header
	movem.l d0-d7/a0-a6,-(sp)
	<load hunk file>
	<clear caches>
	movem.l (sp)+,d0-d7/a0-a6
	movea.l rootHunks(pc),a0	; first root hunk memory
	moveq #0,d0
	rts
...
rootHunks:	ds.l	MAX_ROOT_HUNKS	; table of pointers (32-bit addresses, longwords)
I'm not sure why this is? I might have trashed something accidentally, or perhaps this is another requirement for the bootblock code?

EDIT: Perhaps the bootblock code has to adhere to the OS calling convention and is allowed to trash d0-d1/a0-a1 but must preserve all others?
hop is offline  
Old 05 June 2022, 11:08   #13
ross
Defendit numerus
 
ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
Quote:
Originally Posted by hop View Post
EDIT: Perhaps the bootblock code has to adhere to the OS calling convention and is allowed to trash d0-d1/a0-a1 but must preserve all others?
This.
ross is offline  
Old 05 June 2022, 12:01   #14
hop
Registered User
 
Join Date: Apr 2019
Location: UK
Posts: 172
Quote:
Originally Posted by ross View Post
This.
Makes perfect sense. A bootblock is a system call so when writing one the user has to follow the conventions. Unfortunately this is likely to be the only system call that most people will ever write!

If possible, it might be worth explicitly stating this at
hop is offline  
Old 05 June 2022, 12:59   #15
StingRay
move.l #$c0ff33,throat
 
StingRay's Avatar
 
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,863
Quote:
Originally Posted by hop View Post
Unfortunately this is likely to be the only system call that most people will ever write!

Could you please elaborate what you mean with this statement? Because if it means what I think it does, it is completely wrong!
StingRay is offline  
Old 05 June 2022, 13:07   #16
hop
Registered User
 
Join Date: Apr 2019
Location: UK
Posts: 172
Quote:
Originally Posted by StingRay View Post
Could you please elaborate what you mean with this statement? Because if it means what I think it does, it is completely wrong!
Apologies - I'm new to this game. Thanks for any clarification.

What I mean is that most coders call system calls e.g. AllocMem from their application code, and and have to remember that d0-d1/a0-a1 could be trashed internally but their other registers they have used will be preserved.

When a bootblock is written by the user, the system calls into the bootblock (application code), so this time the user has to manually implement the same system convention. Kind of upside down.

I guess I'm wrong here because there a calls like Supervisor() userfunc which follow the same callback type pattern.
hop is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
fd2pragma inline entry for function that returns pointer to another function Sim085 Coders. C/C++ 11 02 March 2022 10:38
Issue with PiMiGA 1.5 and Speedlink Completion Pro. Jonny0r support.OtherUAE 6 17 March 2021 17:55
Tab Completion in AmigaDOS robotriot support.Apps 5 04 January 2019 12:33
ViNCEd tab completion not working on OS 1.3 Giuseppe support.Apps 4 21 January 2013 02:54
Games you played to completion over and over and never got sick of CaptainNow Nostalgia & memories 60 16 December 2011 00:42

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 17:10.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.10758 seconds with 16 queries