I was looking into something similar in the past - changing the order of the disks and the network cards for a monolithic kernel.
The order how the drivers are loaded gets decided during compilation - by initcall_levels (from lower to higher, include/linux/init.h) and then by
positions in the Makefiles.
I do not think there is much room for playing with initcall_levels - there are too many dependencies.
SATA level 4
in drivers/ata/libata-core.c
at subsys_initcall(ata_init)
MEGASAS level 6 in
drivers/scsi/megaraid/megaraid_sas_base.cat
module_init(megasas_init)
Pointers in System.map:
ffffffff829545cd t megasas_init
ffffffff8295547c t ata_init
ffffffff829e7688 t __initcall_megasas_init6
ffffffff829e8288 t __initcall_ata_init4
Changing the order in the Makefile should be an option, for example in drivers/net/ethernet/intel/Makefile switching the lines for e1000 and e1000e
will change the order for eth0 and eth1 (using net.ifnames=0)
obj-$(CONFIG_E1000) += e1000/
obj-$(CONFIG_E1000E) += e1000e/
So in drivers/Makefile moving ata before scsi
obj-$(CONFIG_ATA) += ata/
obj-y += scsi/
should change the order of the host controllers (SATAs first). Check by
ls -l /sys/class/scsi_host/
lsscsi
But even when having SATA as host0 the disks at LSI controller were found
first, I am not sure how the asynchronous SCSI probe works, but adding a
little delay (e.g. 700 ms) somewhere at the beginning of megasas_init()
in drivers/scsi/megaraid/megaraid_sas_base.c made the SATA disk to be /dev/sda
static int __init megasas_init(void)
{
int rval;
msleep(700);
...
I hope it does not cause any issues in the kernel, it worked for me but be
careful. Of course there are dependencies, not everything is possible. For example
I know when I tried mptsas (drivers/message/fusion/) before scsi, it would
compile, but the kernel immediately crashed at boot.
Hope this helps.