Commit 2b665896 authored by Jeffrey Lee's avatar Jeffrey Lee Committed by ROOL
Browse files

Allow RW/ZI sections to be used

* Instruct the linker to place any RW/ZI data sections in the last ~16MB
of the memory map, starting from &ff000000 (with the current toolchain,
giving it a fixed base address is much easier than giving it a variable
base address)
* The RW/ZI section is mapped as completely inaccessible to user mode
* The initial content of the RW section is copied over shortly after MMU
startup (in Continue_after_HALInit)
* Since link's -bin option produces a file containing a copy of the
(zero-initialised) ZI section, the kernel binary is now produced from a
"binary with AIF header" AIF with the help of the new 'kstrip' tool.
kstrip extracts just the RO and RW sections, ensuring the ROM doesn't
contain a redundant block of zeros for the ZI section.

This should make it easier to use C code & arbitrary libraries within
the kernel, providing they're compiled with suitable settings (e.g.
non-module, no FP, no stack checking, like HALs typically use)
parent 9bc4a580
......@@ -5,3 +5,4 @@
/o/
/rm/
/s/TokHelpSrc
kstrip
......@@ -88,11 +88,11 @@ inst_dirs:
install: ${EXPORTS} inst_dirs
@${ECHO} ${COMPONENT}: header files installed
${KERNEL_MODULE}: ${ROM_OBJECTS} ${DIRS}
${KERNEL_MODULE}: ${ROM_OBJECTS} ${DIRS} ${LIBS} kstrip
${MKDIR} bin
SetEval KernelBase "4" + STR ( 227858432 + ( HALSize LEFT ( LEN HALSize - 1 ) ) * 1024 )
Do ${LD} -bin -base <KernelBase> -o $@ ${ROM_OBJECTS}
Do ${LD} -aif -base <KernelBase> -bin -d -o ${KERNEL_MODULE}_aif ${ROM_OBJECTS}
Do ${LD} -aif -base <KernelBase> -RW-base 0xff000000 -bin -d -o ${KERNEL_MODULE}_aif ${ROM_OBJECTS} ${LIBS}
Do kstrip ${KERNEL_MODULE}_aif ${KERNEL_MODULE}
${TOGPA} -s ${KERNEL_MODULE}_aif ${KERNEL_MODULE}_gpa
GetAll.o: ${TOKHELPSRC}
......@@ -210,5 +210,9 @@ Global.h.VIDCList: hdr.VIDCList
clean::
${XWIPE} Global ${WFLAGS}
${XWIPE} bin ${WFLAGS}
${RM} kstrip
kstrip: kstrip.c
${MAKE} -f kstrip/mk COMPONENT=kstrip THROWBACK=${THROWBACK}
# Dynamic dependencies:
......@@ -15,3 +15,4 @@
Dir <Obey$Dir>
amu_machine clean
stripdepnd
stripdepnd kstrip/mk
/*
* Copyright (c) 2021, RISC OS Open Ltd
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of RISC OS Open Ltd nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
static FILE *out = NULL;
static const char *deleteme = NULL;
static void cleanup(void)
{
if (out)
{
fclose(out);
out = NULL;
}
if (deleteme)
{
remove(deleteme);
}
}
static void must_read(void *buf,size_t size,FILE *f)
{
size_t amt = fread(buf,1,size,f);
if (amt != size)
{
fprintf(stderr,"Failed reading input\n");
exit(1);
}
}
static void must_write(void *buf,size_t size,FILE *f)
{
size_t amt = fwrite(buf,1,size,f);
if (amt != size)
{
fprintf(stderr,"Failed writing output\n");
exit(1);
}
}
#define W(X) (header[X] + (header[X+1]<<8) + (header[X+2]<<16) + (header[X+3]<<24))
/* Load an AIF and extract just the RO and RW segments */
int main(int argc,char **argv)
{
if (argc != 3)
{
fprintf(stderr,"Usage: kstrip <in> <out>\n");
exit(1);
}
FILE *in = fopen(argv[1],"rb");
out = fopen(argv[2],"wb");
if (out)
{
deleteme = argv[2];
atexit(cleanup);
}
if (!in || !out)
{
fprintf(stderr,"Failed to open input/output\n");
exit(1);
}
uint8_t header[128];
must_read(header,128,in);
uint32_t ro_size = W(0x14);
uint32_t rw_size = W(0x18);
printf("RO size %8x\n",ro_size);
printf("RW size %8x\n",rw_size);
uint32_t total = ro_size + rw_size;
printf("Total %8x\n",total);
void *buf = malloc(total);
if (!buf)
{
fprintf(stderr,"Failed to get memory\n");
exit(1);
}
must_read(buf,total,in);
must_write(buf,total,out);
deleteme = NULL;
fclose(in);
fclose(out);
free(buf);
return 0;
}
......@@ -325,6 +325,7 @@ WorkspaceLimit # 0
ROM * &FC000000
ROMatTop SETL {TRUE}
ASSERT ROM >= WorkspaceLimit
RWBase * &FF000000 ; ~16MB of RW data space available to C code
IRQSTK * IRQStackAddress + IRQStackSize
......
# Copyright (c) 2021, RISC OS Open Ltd
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of RISC OS Open Ltd nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# Makefile for kstrip
include CApp
include HostTools
# Dynamic dependencies:
......@@ -155,6 +155,7 @@ ABTStack DefAreaFlags None, PageFlags_Unavailable
UNDStack DefAreaFlags None, PageFlags_Unavailable
Kbuffs DefAreaFlags Read, PageFlags_Unavailable
DebuggerSpace DefAreaFlags Read, PageFlags_Unavailable
RWArea DefAreaFlags None, PageFlags_Unavailable
[ DA_Batman
ChangeDyn_Batcall * -3 ; special DA number to select Batman usage of OS_ChangeDynamicArea
......
......@@ -176,7 +176,10 @@ EndOfAMB
! 0, "AMB section size = &" :CC: :STR: (EndOfAMB - StartOfAMB)
AREA zzzzzz, DATA, READONLY
EndOfKernel
EndOfKernelRO
AREA zzzzzzz, DATA
EndOfKernelRW
DCD 0
END
......@@ -1537,6 +1537,17 @@ ROMDecompAlign_$pt * 20
LDR a3, =(KbuffsSize + &FFF) :AND: &FFFFF000 ;(round to 4k)
BL Init_MapInRAM_Clear_$pt
; Allocate the RW/ZI data segment
IMPORT |Image$$RW$$Base|
LDR a1, =|Image$$RW$$Base|
LDR a2, =AreaFlags_RWArea
IMPORT |Image$$ZI$$Limit|
LDR a3, =|Image$$ZI$$Limit|+&FFF
SUB a3, a3, a1
BIC a3, a3, #&FF
BIC a3, a3, #&F00
BL Init_MapInRAM_Clear_$pt
[ HiProcVecs
; Map in DebuggerSpace
LDR a1, =DebuggerSpace
......
......@@ -320,7 +320,7 @@ RISCOS_Header
DCD (RISCOS_Entries_End - RISCOS_Entries) / 4
DCD OSROM_ImageSize*1024 - OSROM_HALSize
DCD 0
DCD EndOfKernel - KernelBaseA
DCD (EndOfKernelRW-RWBase)+EndOfKernelRO - KernelBaseA
ASSERT (. - RISCOS_Header) = OSHdr_size
RISCOS_Entries
......
......@@ -1212,7 +1212,8 @@ ReleasePhysAddr
; 14=DebuggerSpace
; 15=Scratch space
; 16=Compatibility page
; 16-31 reserved (set to 0)
; 17=RW data section
; 18-31 reserved (set to 0)
;
; Out: r1 = base of area
; r2 = address space allocated for area (whole number of pages)
......@@ -1248,6 +1249,7 @@ MAI_TableStart
B MAI_DebuggerSpace
B MAI_ScratchSpace
B MAI_CompatibilityPage
B MAI_RWData
MAI_TableEnd
70
......@@ -1399,6 +1401,15 @@ MAI_CompatibilityPage
]
EXIT
MAI_RWData
LDR r1, =|Image$$RW$$Base|
LDR r2, =|Image$$ZI$$Limit|+&FFF
SUB r2, r2, r1
BIC r2, r2, #&FF
BIC r2, r2, #&F00
MOV r3, r2
EXIT
;----------------------------------------------------------------------------------------
;
; In: r0 = flags
......@@ -2503,6 +2514,13 @@ CheckMemoryAccess ROUT
LDR r4, =OSROM_ImageSize*1024
LDR r5, =CMA_ROM
BL CMA_AddRange
ASSERT RWBase > ROM
LDR r3, =RWBase
LDR r4, =|Image$$ZI$$Limit|+&FFF-RWBase
BIC r4, r4, #&FF
BIC r4, r4, #&F00
LDR r5, =CMA_RWArea
BL CMA_AddRange
; Finally, high processor vectors/relocated zero page
ASSERT ProcVecs = ZeroPage
[ ZeroPage > 0
......
......@@ -103,6 +103,19 @@ CONT_Break
; Entry point from HALInit
Continue_after_HALInit
; Initialise the RW data segment
IMPORT |Image$$RW$$Base|
IMPORT |Image$$RO$$Limit|
IMPORT |Image$$ZI$$Base|
LDR R0, =|Image$$RW$$Base|
LDR R1, =|Image$$RO$$Limit|
LDR R2, =|Image$$ZI$$Base|
31
CMP R0, R2
LDRNE R3, [R1], #4
STRNE R3, [R0], #4
BNE %BT31
; OK, there is quite a bit of code poking below, to various addresses. We'll
; defer IMB consideration till the poking's done, then do a full IMB (full
......
......@@ -18,7 +18,7 @@
; Arthur Utility commands
SysModules_Info ROUT ; start of ROM modules chain
& EndOfKernel-SysModules_Info
& (EndOfKernelRW-RWBase)+EndOfKernelRO-SysModules_Info
UtilityMod
Module_BaseAddr
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment