So early computers usually got their instructions from two switches. You would start with switch A low and then set switch B to the first bit to load into memory. Then set A high to read B into memory. Set A low and then change B to the second bit you wanted to load. Then set A high to read it into memory. Repeat for each bit in your program. Then hit the run switch.
This takes a lot of time and is prone to errors. So you automate it by using a punch card store the bits in your program on paper and auto flip A as you move the card through the reader and replace B with a optical switch reading the light that passes through hole in the punch card or not depending on the value of the bit.
Now you have reusable pieces of code you can feed in. You find there are some common starter cards that everybody always uses first to setup basic functionality. To speed up load time by not having to feed the same stack of cards in at the start you move their content onto a bunch of magnetic coils and change the hardware to first load that into memory when turned on and then start reading cards. That’s your early bios.
Improve the capacity of system over many years and you have a system that dumps a chunk of the memory onto a sweeping electron beam and by altering that memory you can change the screen the beam is hitting. Giving you a display. Add stuff to take input from a keyboard and you can give command much faster.
Write code that does common tasks and listens to the keyboard so for example when you type flush it clears all memory outside a protected area where these macros are stored. Make enough of these and you have the beginnings of an os.
For a programming language you design the language and then in assembly write programs that parse text and according to the rules of the language generate assembly code that does what the higher language says that instruction should do.
Once you have that you can start writing a second compiler for your language but this time you write that compiler in your new language. One of the major milestones of a language is when it can compile a compiler written in it’s own language.
Now that we have other programming languages the first compiler is usually written in another language and then rewritten in the new language. So the C compiler was written in PDP11 and the Java compiler was written in C. Now the Java compiler is written in Java though the runtime is still in C with I think some C++ depending on the target platform.
I’ve glossed over a lot but this should give you a basic idea. A lot of tedious work at first that gets more and more automated as you go on.
Bit I’m usually better at it then the other person.