davmac314 wrote:That seems a little whack. Since you've just set ". = 16" won't the next line put ".text" right on the 4k mark? Which means ". = 16" is effectively ". = 4K".
It depends on if you count alignment space a part of the kernel. But it would make more sense to just align the entire base on a 4K aligned area.
davmac314 wrote:No, it won't, due to the kernel really starting at 4k and due to the fact that subtracting 16 from a uint32_t pointer will effectively subtract 64 (i.e. 16 * sizeof(uint32_t)) before the conversion back to integer. And you really should use a cast (from pointer type back to uint32_t). (And if this is for a 64-bit kernel you'll want to use a uint64_t instead, or you'll get a compilation error).
I suggest using an opaque, never-defined struct type instead of an array, and casting to char * for the arithmetic:
I admit that part of my post was erroneous. I would recommend this then:
Code: Select all
extern uint8_t end;
uint32_t ksize = (uint32_t)&end - 16;
Then you avoid the the more confusing casts.
davmac314 wrote:The address is virtual, it doesn't need to correspond to the physical address where the kernel is loaded.
The OP hasn't specified if they have set up paging, so I don't know.
Thank you, can a pointer be used instead of the array? i.e something like this
```
extern uint32_t *end;
```
or an array must be used?
It could be a pointer, using would just need to take the address of the pointer, e.g.:
Code: Select all
extern uint32_t* end;
uint32_t ksize = (uint32_t)&end - 16;
kzinti wrote:Building on the previous reply, why not simply define a symbol at the start of the kernel as well.
That's a good idea. I would definitely recommend doing that.