It is possible to handle the paging initialization either before or within the "C" part of the kernel. However, when paging is enabled within the C kernel, it is preferable to keep the kernel region identically mapped (so that you can still use the same logical addresses for the kernel with or without paging).
If you want to load your kernel in high addresses like 0xC000.0000 .. 0xFFFF.FFFF like Linux does, it is probably easier to initialize paging before you execute the kernel - as these addresses are unlikely to be valid memory without paging...
If you see nothing wrong with having your kernel located in the low memory range (either real mode area or just starting at 1Mb), then you can just keep the same mapping.
As people might want to keep 1MB area free for the use of VM86 programs, the "kernel in low area" seems not to be in the mood.
What you could also do is
1. load your kernel in physical memory starting at 1MB.
2. have no paging at start-up, but a kernel code & data segment that have a base such as 1MB == 3GB (0xC000.0000)
3. Enable paging mapping logical linear address 0xC000.0000 -> ... to physical addresses 0x0010.0000 -> ...)
4. Reset the base of kernel code & data segment so that you have a flat-mode kernel.
From a "programming" point of view, everything remains at the same address and using the same physical memory. You just played on the 2 aspects of the MMU to keep the same translation before and after paging enabling.
Keeping cs.base!=0 is not wishable as it usually prevent the use of fast system calls, etc.
may the CR3 be with You, Use it wisely