I have customized the go-ethereum code a bit, compiled and running on 3 nodes (1 miner 1 bootnode 1 fullnode) in my private-net. I just wondered that why should I initialize genesis.json on each node? Otherwise nodes did not found each other. Also, in the beginning, does a fresh node start to synchronize from genesis block or sth else? Here, I just want to understand how the ethereum node discovery works for a node alone? or do they know some nodes be default?
Bootnodes are (can be) hardcoded into the code base.
When you start the node (geth) normally it goes and gets bootnode endoes from here ^ and tries to connect to them.
If you are running your own network you can modify them like I did here for a project that forked ethereum.
I replaced the ethereum boot nodes with my own bootnodes so every time my geth was run it looked for my networks nodes not the Ethereum nodes, this way your nodes should all be finding each other on your private network.
there a some steps to process when you start a node: 1. load bootstrap nodes into router; 2. load seeds from database into router by randomly; and then, node tries to connect these nodes. so , if you have 3 nodes, you could make one as bootstrap which others could connect to according to modify there configuration file.