I know that Ethereum runs in virtual byte code and there's a javascript-like wrapper language called Solidity. This question is about why the developers chose this approach?
I'm not the developers, so I can't say exactly why. They did try to document some of this though in their rationale document
What makes it infeasible to write a smart contract blockchain in pure Python or Javascript? What are the advantages of doing it Ethereum's way?
If properly sandboxed there is no reason Python or Javascript could not be used. However, the complexities of garbage collection and assigning a gas cost to every operation is a clear hurdle to overcome. I work on a separate project that integrates the EVM into a separate blockchain and I recently did some prototyping so that smart contracts could be written in C (x86 VM). It produced very efficient and compact bytecode, but C is definitely not the language you would want to write a smart contract in due to it's memory safety issues and various pitfalls.
Why did Ethereum choose to write its blockchain on EVM? Why is the EVM so limited, and how does it look under the hood?
The EVM was designed to be very simplistic and consistent in it's set of available opcodes. As such, almost every opcode works on 256-bit integers. This extends even to the available memory address space. However, using anything beyond maybe 20 bits of memory address space would most likely exceed the block gas limit due to the memory architecture used. Contract memory space can't have gaps, so if you try to write to address 0xFFFF, it will actually charge you for 64Kbytes of memory, even if you only intended to write a single byte. Along with this, the storage model used for persistence of data is also 256-bit based. It is effectively a key-value space where the key (address) is 256-bits wide, and the value is also 256-bits. Although the EVM has access to memory etc, it is primarily a stack based machine, where each word in the stack is 256-bits. So each opcode takes a series of arguments from the stack, rather than registers or directly specifying memory as in some VMs and CPU architectures.
This consistency and simplicity of the EVM allows a gas model to be made without a great amount of effort, and allows for the EVM's behavior to be more easily audited and implemented.