Improve memory/page init

Align heap start and caculate number of reserved pages
according to the length of ram available.

See
https://gitee.com/unicornx/riscv-operating-system-mooc/issues/I9LNCF.

Signed-off-by: Chen Wang <unicorn_wang@outlook.com>
This commit is contained in:
Chen Wang
2024-06-04 21:15:33 +08:00
parent 0e16685c97
commit eb61470e22
33 changed files with 428 additions and 64 deletions

View File

@@ -1,4 +1,4 @@
LDFLAGS = -Ttext=0x80000000
USE_LINKER_SCRIPT = false
SRCS_ASM = \
start.S \

View File

@@ -1,4 +1,4 @@
LDFLAGS = -Ttext=0x80000000
USE_LINKER_SCRIPT = false
SRCS_ASM = \
start.S \

View File

@@ -3,6 +3,8 @@
* Linker script for outputting to RVOS
*/
#include "platform.h"
/*
* https://sourceware.org/binutils/docs/ld/Miscellaneous-Commands.html
* OUTPUT_ARCH command specifies a particular output machine architecture.
@@ -47,7 +49,7 @@ ENTRY( _start )
*/
MEMORY
{
ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 128M
ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = LENGTH_RAM
}
/*

View File

@@ -76,22 +76,52 @@ static inline ptr_t _align_page(ptr_t address)
return (address + order) & (~order);
}
/*
* ______________________________HEAP_SIZE_______________________________
* / ___num_reserved_pages___ ______________num_pages______________ \
* / / \ / \ \
* |---|<--Page-->|<--Page-->|...|<--Page-->|<--Page-->|......|<--Page-->|---|
* A A A A A
* | | | | |
* | | | | _memory_end
* | | | |
* | _heap_start_aligned _alloc_start _alloc_end
* HEAP_START(BSS_END)
*
* Note: _alloc_end may equal to _memory_end.
*/
void page_init()
{
ptr_t _heap_start_aligned = _align_page(HEAP_START);
/*
* We reserved 8 Page (8 x 4096) to hold the Page structures.
* It should be enough to manage at most 128 MB (8 x 4096 x 4096)
* We reserved some Pages to hold the Page structures.
* The number of reserved pages depends on the LENGTH_RAM.
* For simplicity, the space we reserve here is just an approximation,
* assuming that it can accommodate the maximum LENGTH_RAM.
* We assume LENGTH_RAM should not be too small, ideally no less
* than 16M (i.e. PAGE_SIZE * PAGE_SIZE).
*/
_num_pages = (HEAP_SIZE / PAGE_SIZE) - 8;
printf("HEAP_START = %p, HEAP_SIZE = 0x%lx, num of pages = %d\n", HEAP_START, HEAP_SIZE, _num_pages);
uint32_t num_reserved_pages = LENGTH_RAM / (PAGE_SIZE * PAGE_SIZE);
_num_pages = (HEAP_SIZE - (_heap_start_aligned - HEAP_START))/ PAGE_SIZE - num_reserved_pages;
printf("HEAP_START = %p(aligned to %p), HEAP_SIZE = 0x%lx,\n"
"num of reserved pages = %d, num of pages to be allocated for heap = %d\n",
HEAP_START, _heap_start_aligned, HEAP_SIZE,
num_reserved_pages, _num_pages);
/*
* We use HEAP_START, not _heap_start_aligned as begin address for
* allocating struct Page, because we have no requirement of alignment
* for position of struct Page.
*/
struct Page *page = (struct Page *)HEAP_START;
for (int i = 0; i < _num_pages; i++) {
_clear(page);
page++;
}
_alloc_start = _align_page(HEAP_START + 8 * PAGE_SIZE);
_alloc_start = _heap_start_aligned + num_reserved_pages * PAGE_SIZE;
_alloc_end = _alloc_start + (PAGE_SIZE * _num_pages);
printf("TEXT: %p -> %p\n", TEXT_START, TEXT_END);

View File

@@ -12,6 +12,9 @@
*/
#define MAXNUM_CPU 8
/* used in os.ld */
#define LENGTH_RAM 128*1024*1024
/*
* MemoryMap
* see https://github.com/qemu/qemu/blob/master/hw/riscv/virt.c, virt_memmap[]

View File

@@ -3,6 +3,8 @@
* Linker script for outputting to RVOS
*/
#include "platform.h"
/*
* https://sourceware.org/binutils/docs/ld/Miscellaneous-Commands.html
* OUTPUT_ARCH command specifies a particular output machine architecture.
@@ -47,7 +49,7 @@ ENTRY( _start )
*/
MEMORY
{
ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 128M
ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = LENGTH_RAM
}
/*

View File

@@ -76,22 +76,52 @@ static inline ptr_t _align_page(ptr_t address)
return (address + order) & (~order);
}
/*
* ______________________________HEAP_SIZE_______________________________
* / ___num_reserved_pages___ ______________num_pages______________ \
* / / \ / \ \
* |---|<--Page-->|<--Page-->|...|<--Page-->|<--Page-->|......|<--Page-->|---|
* A A A A A
* | | | | |
* | | | | _memory_end
* | | | |
* | _heap_start_aligned _alloc_start _alloc_end
* HEAP_START(BSS_END)
*
* Note: _alloc_end may equal to _memory_end.
*/
void page_init()
{
ptr_t _heap_start_aligned = _align_page(HEAP_START);
/*
* We reserved 8 Page (8 x 4096) to hold the Page structures.
* It should be enough to manage at most 128 MB (8 x 4096 x 4096)
* We reserved some Pages to hold the Page structures.
* The number of reserved pages depends on the LENGTH_RAM.
* For simplicity, the space we reserve here is just an approximation,
* assuming that it can accommodate the maximum LENGTH_RAM.
* We assume LENGTH_RAM should not be too small, ideally no less
* than 16M (i.e. PAGE_SIZE * PAGE_SIZE).
*/
_num_pages = (HEAP_SIZE / PAGE_SIZE) - 8;
printf("HEAP_START = %p, HEAP_SIZE = 0x%lx, num of pages = %d\n", HEAP_START, HEAP_SIZE, _num_pages);
uint32_t num_reserved_pages = LENGTH_RAM / (PAGE_SIZE * PAGE_SIZE);
_num_pages = (HEAP_SIZE - (_heap_start_aligned - HEAP_START))/ PAGE_SIZE - num_reserved_pages;
printf("HEAP_START = %p(aligned to %p), HEAP_SIZE = 0x%lx,\n"
"num of reserved pages = %d, num of pages to be allocated for heap = %d\n",
HEAP_START, _heap_start_aligned, HEAP_SIZE,
num_reserved_pages, _num_pages);
/*
* We use HEAP_START, not _heap_start_aligned as begin address for
* allocating struct Page, because we have no requirement of alignment
* for position of struct Page.
*/
struct Page *page = (struct Page *)HEAP_START;
for (int i = 0; i < _num_pages; i++) {
_clear(page);
page++;
}
_alloc_start = _align_page(HEAP_START + 8 * PAGE_SIZE);
_alloc_start = _heap_start_aligned + num_reserved_pages * PAGE_SIZE;
_alloc_end = _alloc_start + (PAGE_SIZE * _num_pages);
printf("TEXT: %p -> %p\n", TEXT_START, TEXT_END);

View File

@@ -12,6 +12,9 @@
*/
#define MAXNUM_CPU 8
/* used in os.ld */
#define LENGTH_RAM 128*1024*1024
/*
* MemoryMap
* see https://github.com/qemu/qemu/blob/master/hw/riscv/virt.c, virt_memmap[]

View File

@@ -3,6 +3,8 @@
* Linker script for outputting to RVOS
*/
#include "platform.h"
/*
* https://sourceware.org/binutils/docs/ld/Miscellaneous-Commands.html
* OUTPUT_ARCH command specifies a particular output machine architecture.
@@ -47,7 +49,7 @@ ENTRY( _start )
*/
MEMORY
{
ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 128M
ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = LENGTH_RAM
}
/*

View File

@@ -76,22 +76,52 @@ static inline ptr_t _align_page(ptr_t address)
return (address + order) & (~order);
}
/*
* ______________________________HEAP_SIZE_______________________________
* / ___num_reserved_pages___ ______________num_pages______________ \
* / / \ / \ \
* |---|<--Page-->|<--Page-->|...|<--Page-->|<--Page-->|......|<--Page-->|---|
* A A A A A
* | | | | |
* | | | | _memory_end
* | | | |
* | _heap_start_aligned _alloc_start _alloc_end
* HEAP_START(BSS_END)
*
* Note: _alloc_end may equal to _memory_end.
*/
void page_init()
{
ptr_t _heap_start_aligned = _align_page(HEAP_START);
/*
* We reserved 8 Page (8 x 4096) to hold the Page structures.
* It should be enough to manage at most 128 MB (8 x 4096 x 4096)
* We reserved some Pages to hold the Page structures.
* The number of reserved pages depends on the LENGTH_RAM.
* For simplicity, the space we reserve here is just an approximation,
* assuming that it can accommodate the maximum LENGTH_RAM.
* We assume LENGTH_RAM should not be too small, ideally no less
* than 16M (i.e. PAGE_SIZE * PAGE_SIZE).
*/
_num_pages = (HEAP_SIZE / PAGE_SIZE) - 8;
printf("HEAP_START = %p, HEAP_SIZE = 0x%lx, num of pages = %d\n", HEAP_START, HEAP_SIZE, _num_pages);
uint32_t num_reserved_pages = LENGTH_RAM / (PAGE_SIZE * PAGE_SIZE);
_num_pages = (HEAP_SIZE - (_heap_start_aligned - HEAP_START))/ PAGE_SIZE - num_reserved_pages;
printf("HEAP_START = %p(aligned to %p), HEAP_SIZE = 0x%lx,\n"
"num of reserved pages = %d, num of pages to be allocated for heap = %d\n",
HEAP_START, _heap_start_aligned, HEAP_SIZE,
num_reserved_pages, _num_pages);
/*
* We use HEAP_START, not _heap_start_aligned as begin address for
* allocating struct Page, because we have no requirement of alignment
* for position of struct Page.
*/
struct Page *page = (struct Page *)HEAP_START;
for (int i = 0; i < _num_pages; i++) {
_clear(page);
page++;
}
_alloc_start = _align_page(HEAP_START + 8 * PAGE_SIZE);
_alloc_start = _heap_start_aligned + num_reserved_pages * PAGE_SIZE;
_alloc_end = _alloc_start + (PAGE_SIZE * _num_pages);
printf("TEXT: %p -> %p\n", TEXT_START, TEXT_END);

View File

@@ -12,6 +12,9 @@
*/
#define MAXNUM_CPU 8
/* used in os.ld */
#define LENGTH_RAM 128*1024*1024
/*
* MemoryMap
* see https://github.com/qemu/qemu/blob/master/hw/riscv/virt.c, virt_memmap[]

View File

@@ -3,6 +3,8 @@
* Linker script for outputting to RVOS
*/
#include "platform.h"
/*
* https://sourceware.org/binutils/docs/ld/Miscellaneous-Commands.html
* OUTPUT_ARCH command specifies a particular output machine architecture.
@@ -47,7 +49,7 @@ ENTRY( _start )
*/
MEMORY
{
ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 128M
ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = LENGTH_RAM
}
/*

View File

@@ -76,22 +76,52 @@ static inline ptr_t _align_page(ptr_t address)
return (address + order) & (~order);
}
/*
* ______________________________HEAP_SIZE_______________________________
* / ___num_reserved_pages___ ______________num_pages______________ \
* / / \ / \ \
* |---|<--Page-->|<--Page-->|...|<--Page-->|<--Page-->|......|<--Page-->|---|
* A A A A A
* | | | | |
* | | | | _memory_end
* | | | |
* | _heap_start_aligned _alloc_start _alloc_end
* HEAP_START(BSS_END)
*
* Note: _alloc_end may equal to _memory_end.
*/
void page_init()
{
ptr_t _heap_start_aligned = _align_page(HEAP_START);
/*
* We reserved 8 Page (8 x 4096) to hold the Page structures.
* It should be enough to manage at most 128 MB (8 x 4096 x 4096)
* We reserved some Pages to hold the Page structures.
* The number of reserved pages depends on the LENGTH_RAM.
* For simplicity, the space we reserve here is just an approximation,
* assuming that it can accommodate the maximum LENGTH_RAM.
* We assume LENGTH_RAM should not be too small, ideally no less
* than 16M (i.e. PAGE_SIZE * PAGE_SIZE).
*/
_num_pages = (HEAP_SIZE / PAGE_SIZE) - 8;
printf("HEAP_START = %p, HEAP_SIZE = 0x%lx, num of pages = %d\n", HEAP_START, HEAP_SIZE, _num_pages);
uint32_t num_reserved_pages = LENGTH_RAM / (PAGE_SIZE * PAGE_SIZE);
_num_pages = (HEAP_SIZE - (_heap_start_aligned - HEAP_START))/ PAGE_SIZE - num_reserved_pages;
printf("HEAP_START = %p(aligned to %p), HEAP_SIZE = 0x%lx,\n"
"num of reserved pages = %d, num of pages to be allocated for heap = %d\n",
HEAP_START, _heap_start_aligned, HEAP_SIZE,
num_reserved_pages, _num_pages);
/*
* We use HEAP_START, not _heap_start_aligned as begin address for
* allocating struct Page, because we have no requirement of alignment
* for position of struct Page.
*/
struct Page *page = (struct Page *)HEAP_START;
for (int i = 0; i < _num_pages; i++) {
_clear(page);
page++;
}
_alloc_start = _align_page(HEAP_START + 8 * PAGE_SIZE);
_alloc_start = _heap_start_aligned + num_reserved_pages * PAGE_SIZE;
_alloc_end = _alloc_start + (PAGE_SIZE * _num_pages);
printf("TEXT: %p -> %p\n", TEXT_START, TEXT_END);

View File

@@ -12,6 +12,9 @@
*/
#define MAXNUM_CPU 8
/* used in os.ld */
#define LENGTH_RAM 128*1024*1024
/*
* MemoryMap
* see https://github.com/qemu/qemu/blob/master/hw/riscv/virt.c, virt_memmap[]

View File

@@ -3,6 +3,8 @@
* Linker script for outputting to RVOS
*/
#include "platform.h"
/*
* https://sourceware.org/binutils/docs/ld/Miscellaneous-Commands.html
* OUTPUT_ARCH command specifies a particular output machine architecture.
@@ -47,7 +49,7 @@ ENTRY( _start )
*/
MEMORY
{
ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 128M
ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = LENGTH_RAM
}
/*

View File

@@ -76,22 +76,52 @@ static inline ptr_t _align_page(ptr_t address)
return (address + order) & (~order);
}
/*
* ______________________________HEAP_SIZE_______________________________
* / ___num_reserved_pages___ ______________num_pages______________ \
* / / \ / \ \
* |---|<--Page-->|<--Page-->|...|<--Page-->|<--Page-->|......|<--Page-->|---|
* A A A A A
* | | | | |
* | | | | _memory_end
* | | | |
* | _heap_start_aligned _alloc_start _alloc_end
* HEAP_START(BSS_END)
*
* Note: _alloc_end may equal to _memory_end.
*/
void page_init()
{
ptr_t _heap_start_aligned = _align_page(HEAP_START);
/*
* We reserved 8 Page (8 x 4096) to hold the Page structures.
* It should be enough to manage at most 128 MB (8 x 4096 x 4096)
* We reserved some Pages to hold the Page structures.
* The number of reserved pages depends on the LENGTH_RAM.
* For simplicity, the space we reserve here is just an approximation,
* assuming that it can accommodate the maximum LENGTH_RAM.
* We assume LENGTH_RAM should not be too small, ideally no less
* than 16M (i.e. PAGE_SIZE * PAGE_SIZE).
*/
_num_pages = (HEAP_SIZE / PAGE_SIZE) - 8;
printf("HEAP_START = %p, HEAP_SIZE = 0x%lx, num of pages = %d\n", HEAP_START, HEAP_SIZE, _num_pages);
uint32_t num_reserved_pages = LENGTH_RAM / (PAGE_SIZE * PAGE_SIZE);
_num_pages = (HEAP_SIZE - (_heap_start_aligned - HEAP_START))/ PAGE_SIZE - num_reserved_pages;
printf("HEAP_START = %p(aligned to %p), HEAP_SIZE = 0x%lx,\n"
"num of reserved pages = %d, num of pages to be allocated for heap = %d\n",
HEAP_START, _heap_start_aligned, HEAP_SIZE,
num_reserved_pages, _num_pages);
/*
* We use HEAP_START, not _heap_start_aligned as begin address for
* allocating struct Page, because we have no requirement of alignment
* for position of struct Page.
*/
struct Page *page = (struct Page *)HEAP_START;
for (int i = 0; i < _num_pages; i++) {
_clear(page);
page++;
}
_alloc_start = _align_page(HEAP_START + 8 * PAGE_SIZE);
_alloc_start = _heap_start_aligned + num_reserved_pages * PAGE_SIZE;
_alloc_end = _alloc_start + (PAGE_SIZE * _num_pages);
printf("TEXT: %p -> %p\n", TEXT_START, TEXT_END);

View File

@@ -12,6 +12,9 @@
*/
#define MAXNUM_CPU 8
/* used in os.ld */
#define LENGTH_RAM 128*1024*1024
/*
* MemoryMap
* see https://github.com/qemu/qemu/blob/master/hw/riscv/virt.c, virt_memmap[]

View File

@@ -3,6 +3,8 @@
* Linker script for outputting to RVOS
*/
#include "platform.h"
/*
* https://sourceware.org/binutils/docs/ld/Miscellaneous-Commands.html
* OUTPUT_ARCH command specifies a particular output machine architecture.
@@ -47,7 +49,7 @@ ENTRY( _start )
*/
MEMORY
{
ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 128M
ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = LENGTH_RAM
}
/*

View File

@@ -76,22 +76,52 @@ static inline ptr_t _align_page(ptr_t address)
return (address + order) & (~order);
}
/*
* ______________________________HEAP_SIZE_______________________________
* / ___num_reserved_pages___ ______________num_pages______________ \
* / / \ / \ \
* |---|<--Page-->|<--Page-->|...|<--Page-->|<--Page-->|......|<--Page-->|---|
* A A A A A
* | | | | |
* | | | | _memory_end
* | | | |
* | _heap_start_aligned _alloc_start _alloc_end
* HEAP_START(BSS_END)
*
* Note: _alloc_end may equal to _memory_end.
*/
void page_init()
{
ptr_t _heap_start_aligned = _align_page(HEAP_START);
/*
* We reserved 8 Page (8 x 4096) to hold the Page structures.
* It should be enough to manage at most 128 MB (8 x 4096 x 4096)
* We reserved some Pages to hold the Page structures.
* The number of reserved pages depends on the LENGTH_RAM.
* For simplicity, the space we reserve here is just an approximation,
* assuming that it can accommodate the maximum LENGTH_RAM.
* We assume LENGTH_RAM should not be too small, ideally no less
* than 16M (i.e. PAGE_SIZE * PAGE_SIZE).
*/
_num_pages = (HEAP_SIZE / PAGE_SIZE) - 8;
printf("HEAP_START = %p, HEAP_SIZE = 0x%lx, num of pages = %d\n", HEAP_START, HEAP_SIZE, _num_pages);
uint32_t num_reserved_pages = LENGTH_RAM / (PAGE_SIZE * PAGE_SIZE);
_num_pages = (HEAP_SIZE - (_heap_start_aligned - HEAP_START))/ PAGE_SIZE - num_reserved_pages;
printf("HEAP_START = %p(aligned to %p), HEAP_SIZE = 0x%lx,\n"
"num of reserved pages = %d, num of pages to be allocated for heap = %d\n",
HEAP_START, _heap_start_aligned, HEAP_SIZE,
num_reserved_pages, _num_pages);
/*
* We use HEAP_START, not _heap_start_aligned as begin address for
* allocating struct Page, because we have no requirement of alignment
* for position of struct Page.
*/
struct Page *page = (struct Page *)HEAP_START;
for (int i = 0; i < _num_pages; i++) {
_clear(page);
page++;
}
_alloc_start = _align_page(HEAP_START + 8 * PAGE_SIZE);
_alloc_start = _heap_start_aligned + num_reserved_pages * PAGE_SIZE;
_alloc_end = _alloc_start + (PAGE_SIZE * _num_pages);
printf("TEXT: %p -> %p\n", TEXT_START, TEXT_END);

View File

@@ -12,6 +12,9 @@
*/
#define MAXNUM_CPU 8
/* used in os.ld */
#define LENGTH_RAM 128*1024*1024
/*
* MemoryMap
* see https://github.com/qemu/qemu/blob/master/hw/riscv/virt.c, virt_memmap[]

View File

@@ -3,6 +3,8 @@
* Linker script for outputting to RVOS
*/
#include "platform.h"
/*
* https://sourceware.org/binutils/docs/ld/Miscellaneous-Commands.html
* OUTPUT_ARCH command specifies a particular output machine architecture.
@@ -47,7 +49,7 @@ ENTRY( _start )
*/
MEMORY
{
ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 128M
ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = LENGTH_RAM
}
/*

View File

@@ -76,22 +76,52 @@ static inline ptr_t _align_page(ptr_t address)
return (address + order) & (~order);
}
/*
* ______________________________HEAP_SIZE_______________________________
* / ___num_reserved_pages___ ______________num_pages______________ \
* / / \ / \ \
* |---|<--Page-->|<--Page-->|...|<--Page-->|<--Page-->|......|<--Page-->|---|
* A A A A A
* | | | | |
* | | | | _memory_end
* | | | |
* | _heap_start_aligned _alloc_start _alloc_end
* HEAP_START(BSS_END)
*
* Note: _alloc_end may equal to _memory_end.
*/
void page_init()
{
ptr_t _heap_start_aligned = _align_page(HEAP_START);
/*
* We reserved 8 Page (8 x 4096) to hold the Page structures.
* It should be enough to manage at most 128 MB (8 x 4096 x 4096)
* We reserved some Pages to hold the Page structures.
* The number of reserved pages depends on the LENGTH_RAM.
* For simplicity, the space we reserve here is just an approximation,
* assuming that it can accommodate the maximum LENGTH_RAM.
* We assume LENGTH_RAM should not be too small, ideally no less
* than 16M (i.e. PAGE_SIZE * PAGE_SIZE).
*/
_num_pages = (HEAP_SIZE / PAGE_SIZE) - 8;
printf("HEAP_START = %p, HEAP_SIZE = 0x%lx, num of pages = %d\n", HEAP_START, HEAP_SIZE, _num_pages);
uint32_t num_reserved_pages = LENGTH_RAM / (PAGE_SIZE * PAGE_SIZE);
_num_pages = (HEAP_SIZE - (_heap_start_aligned - HEAP_START))/ PAGE_SIZE - num_reserved_pages;
printf("HEAP_START = %p(aligned to %p), HEAP_SIZE = 0x%lx,\n"
"num of reserved pages = %d, num of pages to be allocated for heap = %d\n",
HEAP_START, _heap_start_aligned, HEAP_SIZE,
num_reserved_pages, _num_pages);
/*
* We use HEAP_START, not _heap_start_aligned as begin address for
* allocating struct Page, because we have no requirement of alignment
* for position of struct Page.
*/
struct Page *page = (struct Page *)HEAP_START;
for (int i = 0; i < _num_pages; i++) {
_clear(page);
page++;
}
_alloc_start = _align_page(HEAP_START + 8 * PAGE_SIZE);
_alloc_start = _heap_start_aligned + num_reserved_pages * PAGE_SIZE;
_alloc_end = _alloc_start + (PAGE_SIZE * _num_pages);
printf("TEXT: %p -> %p\n", TEXT_START, TEXT_END);

View File

@@ -12,6 +12,9 @@
*/
#define MAXNUM_CPU 8
/* used in os.ld */
#define LENGTH_RAM 128*1024*1024
/*
* MemoryMap
* see https://github.com/qemu/qemu/blob/master/hw/riscv/virt.c, virt_memmap[]

View File

@@ -3,6 +3,8 @@
* Linker script for outputting to RVOS
*/
#include "platform.h"
/*
* https://sourceware.org/binutils/docs/ld/Miscellaneous-Commands.html
* OUTPUT_ARCH command specifies a particular output machine architecture.
@@ -47,7 +49,7 @@ ENTRY( _start )
*/
MEMORY
{
ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 128M
ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = LENGTH_RAM
}
/*

View File

@@ -76,22 +76,52 @@ static inline ptr_t _align_page(ptr_t address)
return (address + order) & (~order);
}
/*
* ______________________________HEAP_SIZE_______________________________
* / ___num_reserved_pages___ ______________num_pages______________ \
* / / \ / \ \
* |---|<--Page-->|<--Page-->|...|<--Page-->|<--Page-->|......|<--Page-->|---|
* A A A A A
* | | | | |
* | | | | _memory_end
* | | | |
* | _heap_start_aligned _alloc_start _alloc_end
* HEAP_START(BSS_END)
*
* Note: _alloc_end may equal to _memory_end.
*/
void page_init()
{
ptr_t _heap_start_aligned = _align_page(HEAP_START);
/*
* We reserved 8 Page (8 x 4096) to hold the Page structures.
* It should be enough to manage at most 128 MB (8 x 4096 x 4096)
* We reserved some Pages to hold the Page structures.
* The number of reserved pages depends on the LENGTH_RAM.
* For simplicity, the space we reserve here is just an approximation,
* assuming that it can accommodate the maximum LENGTH_RAM.
* We assume LENGTH_RAM should not be too small, ideally no less
* than 16M (i.e. PAGE_SIZE * PAGE_SIZE).
*/
_num_pages = (HEAP_SIZE / PAGE_SIZE) - 8;
printf("HEAP_START = %p, HEAP_SIZE = 0x%lx, num of pages = %d\n", HEAP_START, HEAP_SIZE, _num_pages);
uint32_t num_reserved_pages = LENGTH_RAM / (PAGE_SIZE * PAGE_SIZE);
_num_pages = (HEAP_SIZE - (_heap_start_aligned - HEAP_START))/ PAGE_SIZE - num_reserved_pages;
printf("HEAP_START = %p(aligned to %p), HEAP_SIZE = 0x%lx,\n"
"num of reserved pages = %d, num of pages to be allocated for heap = %d\n",
HEAP_START, _heap_start_aligned, HEAP_SIZE,
num_reserved_pages, _num_pages);
/*
* We use HEAP_START, not _heap_start_aligned as begin address for
* allocating struct Page, because we have no requirement of alignment
* for position of struct Page.
*/
struct Page *page = (struct Page *)HEAP_START;
for (int i = 0; i < _num_pages; i++) {
_clear(page);
page++;
}
_alloc_start = _align_page(HEAP_START + 8 * PAGE_SIZE);
_alloc_start = _heap_start_aligned + num_reserved_pages * PAGE_SIZE;
_alloc_end = _alloc_start + (PAGE_SIZE * _num_pages);
printf("TEXT: %p -> %p\n", TEXT_START, TEXT_END);

View File

@@ -12,6 +12,9 @@
*/
#define MAXNUM_CPU 8
/* used in os.ld */
#define LENGTH_RAM 128*1024*1024
/*
* MemoryMap
* see https://github.com/qemu/qemu/blob/master/hw/riscv/virt.c, virt_memmap[]

View File

@@ -3,6 +3,8 @@
* Linker script for outputting to RVOS
*/
#include "platform.h"
/*
* https://sourceware.org/binutils/docs/ld/Miscellaneous-Commands.html
* OUTPUT_ARCH command specifies a particular output machine architecture.
@@ -47,7 +49,7 @@ ENTRY( _start )
*/
MEMORY
{
ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 128M
ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = LENGTH_RAM
}
/*

View File

@@ -76,22 +76,52 @@ static inline ptr_t _align_page(ptr_t address)
return (address + order) & (~order);
}
/*
* ______________________________HEAP_SIZE_______________________________
* / ___num_reserved_pages___ ______________num_pages______________ \
* / / \ / \ \
* |---|<--Page-->|<--Page-->|...|<--Page-->|<--Page-->|......|<--Page-->|---|
* A A A A A
* | | | | |
* | | | | _memory_end
* | | | |
* | _heap_start_aligned _alloc_start _alloc_end
* HEAP_START(BSS_END)
*
* Note: _alloc_end may equal to _memory_end.
*/
void page_init()
{
ptr_t _heap_start_aligned = _align_page(HEAP_START);
/*
* We reserved 8 Page (8 x 4096) to hold the Page structures.
* It should be enough to manage at most 128 MB (8 x 4096 x 4096)
* We reserved some Pages to hold the Page structures.
* The number of reserved pages depends on the LENGTH_RAM.
* For simplicity, the space we reserve here is just an approximation,
* assuming that it can accommodate the maximum LENGTH_RAM.
* We assume LENGTH_RAM should not be too small, ideally no less
* than 16M (i.e. PAGE_SIZE * PAGE_SIZE).
*/
_num_pages = (HEAP_SIZE / PAGE_SIZE) - 8;
printf("HEAP_START = %p, HEAP_SIZE = 0x%lx, num of pages = %d\n", HEAP_START, HEAP_SIZE, _num_pages);
uint32_t num_reserved_pages = LENGTH_RAM / (PAGE_SIZE * PAGE_SIZE);
_num_pages = (HEAP_SIZE - (_heap_start_aligned - HEAP_START))/ PAGE_SIZE - num_reserved_pages;
printf("HEAP_START = %p(aligned to %p), HEAP_SIZE = 0x%lx,\n"
"num of reserved pages = %d, num of pages to be allocated for heap = %d\n",
HEAP_START, _heap_start_aligned, HEAP_SIZE,
num_reserved_pages, _num_pages);
/*
* We use HEAP_START, not _heap_start_aligned as begin address for
* allocating struct Page, because we have no requirement of alignment
* for position of struct Page.
*/
struct Page *page = (struct Page *)HEAP_START;
for (int i = 0; i < _num_pages; i++) {
_clear(page);
page++;
}
_alloc_start = _align_page(HEAP_START + 8 * PAGE_SIZE);
_alloc_start = _heap_start_aligned + num_reserved_pages * PAGE_SIZE;
_alloc_end = _alloc_start + (PAGE_SIZE * _num_pages);
printf("TEXT: %p -> %p\n", TEXT_START, TEXT_END);

View File

@@ -12,6 +12,9 @@
*/
#define MAXNUM_CPU 8
/* used in os.ld */
#define LENGTH_RAM 128*1024*1024
/*
* MemoryMap
* see https://github.com/qemu/qemu/blob/master/hw/riscv/virt.c, virt_memmap[]

View File

@@ -3,6 +3,8 @@
* Linker script for outputting to RVOS
*/
#include "platform.h"
/*
* https://sourceware.org/binutils/docs/ld/Miscellaneous-Commands.html
* OUTPUT_ARCH command specifies a particular output machine architecture.
@@ -47,7 +49,7 @@ ENTRY( _start )
*/
MEMORY
{
ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 128M
ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = LENGTH_RAM
}
/*

View File

@@ -76,22 +76,52 @@ static inline ptr_t _align_page(ptr_t address)
return (address + order) & (~order);
}
/*
* ______________________________HEAP_SIZE_______________________________
* / ___num_reserved_pages___ ______________num_pages______________ \
* / / \ / \ \
* |---|<--Page-->|<--Page-->|...|<--Page-->|<--Page-->|......|<--Page-->|---|
* A A A A A
* | | | | |
* | | | | _memory_end
* | | | |
* | _heap_start_aligned _alloc_start _alloc_end
* HEAP_START(BSS_END)
*
* Note: _alloc_end may equal to _memory_end.
*/
void page_init()
{
ptr_t _heap_start_aligned = _align_page(HEAP_START);
/*
* We reserved 8 Page (8 x 4096) to hold the Page structures.
* It should be enough to manage at most 128 MB (8 x 4096 x 4096)
* We reserved some Pages to hold the Page structures.
* The number of reserved pages depends on the LENGTH_RAM.
* For simplicity, the space we reserve here is just an approximation,
* assuming that it can accommodate the maximum LENGTH_RAM.
* We assume LENGTH_RAM should not be too small, ideally no less
* than 16M (i.e. PAGE_SIZE * PAGE_SIZE).
*/
_num_pages = (HEAP_SIZE / PAGE_SIZE) - 8;
printf("HEAP_START = %p, HEAP_SIZE = 0x%lx, num of pages = %d\n", HEAP_START, HEAP_SIZE, _num_pages);
uint32_t num_reserved_pages = LENGTH_RAM / (PAGE_SIZE * PAGE_SIZE);
_num_pages = (HEAP_SIZE - (_heap_start_aligned - HEAP_START))/ PAGE_SIZE - num_reserved_pages;
printf("HEAP_START = %p(aligned to %p), HEAP_SIZE = 0x%lx,\n"
"num of reserved pages = %d, num of pages to be allocated for heap = %d\n",
HEAP_START, _heap_start_aligned, HEAP_SIZE,
num_reserved_pages, _num_pages);
/*
* We use HEAP_START, not _heap_start_aligned as begin address for
* allocating struct Page, because we have no requirement of alignment
* for position of struct Page.
*/
struct Page *page = (struct Page *)HEAP_START;
for (int i = 0; i < _num_pages; i++) {
_clear(page);
page++;
}
_alloc_start = _align_page(HEAP_START + 8 * PAGE_SIZE);
_alloc_start = _heap_start_aligned + num_reserved_pages * PAGE_SIZE;
_alloc_end = _alloc_start + (PAGE_SIZE * _num_pages);
printf("TEXT: %p -> %p\n", TEXT_START, TEXT_END);

View File

@@ -12,6 +12,9 @@
*/
#define MAXNUM_CPU 8
/* used in os.ld */
#define LENGTH_RAM 128*1024*1024
/*
* MemoryMap
* see https://github.com/qemu/qemu/blob/master/hw/riscv/virt.c, virt_memmap[]

View File

@@ -3,14 +3,12 @@
# Custom Macro Definition (Common part)
include ../defines.mk
DEFS +=
CROSS_COMPILE = riscv64-unknown-elf-
CFLAGS += -nostdlib -fno-builtin -g -Wall
CFLAGS += -march=rv32g -mabi=ilp32
LDFLAGS ?= -T os.ld
QEMU = qemu-system-riscv32
QFLAGS = -nographic -smp 1 -machine virt -bios none
@@ -32,6 +30,13 @@ OBJS = ${OBJS_ASM} ${OBJS_C}
ELF = ${OUTPUT_PATH}/os.elf
BIN = ${OUTPUT_PATH}/os.bin
USE_LINKER_SCRIPT ?= true
ifeq (${USE_LINKER_SCRIPT}, true)
LDFLAGS = -T ${OUTPUT_PATH}/os.ld.generated
else
LDFLAGS = -Ttext=0x80000000
endif
.DEFAULT_GOAL := all
all: ${OUTPUT_PATH} ${ELF}
@@ -39,7 +44,16 @@ ${OUTPUT_PATH}:
@${MKDIR} $@
# start.o must be the first in dependency!
#
# For USE_LINKER_SCRIPT == true, before do link, run preprocessor manually for
# linker script.
# -E specifies GCC to only run preprocessor
# -P prevents preprocessor from generating linemarkers (#line directives)
# -x c tells GCC to treat your linker script as C source file
${ELF}: ${OBJS}
ifeq (${USE_LINKER_SCRIPT}, true)
${CC} -E -P -x c ${DEFS} ${CFLAGS} os.ld > ${OUTPUT_PATH}/os.ld.generated
endif
${CC} ${CFLAGS} ${LDFLAGS} -o ${ELF} $^
${OBJCOPY} -O binary ${ELF} ${BIN}