Keyboards send events to the computer. An event says “scan code nnn down” or “scan code nnn up”. At the other end of the chain, applications running in a terminal expect input in the form of a sequence of characters. (Unless they've requested raw access, like the X server does.) When you press A, the keyboard sends the information “scan code 38 down”. The console driver looks up its keymap and transforms this into “character
a” (if no modifier key is pressed).
When you press a key or key combination that doesn't result in a character, the information needs to be encoded in terms of characters. A few keys and key combinations have corresponding control characters, e.g. Ctrl+A sends the character
␁ (byte value 1), Return sends the character
␍ (Ctrl+M, byte value 13), etc. Most function keys don't have a corresponding character and instead send a sequence of characters that starts with the
␛ (escape, byte value 27) character. For example, the key Up is translated into the escape sequence
␛[A (three characters: escape, open bracket, capital A).
The user name prompt on the console is dumb and doesn't understand most escape sequences. It doesn't have the line edition and history features that you're used to: those are provided by the shell, and until you log in, you don't have a shell. So it simply displays the escape sequence. There is no glyph for the
␛ character, so it's displayed as
^ sign is traditionally used as a prefix for control characters, and escape is
^[ because of its byte value: it's the byte value of
[, minus 64.
If you press Up at a shell prompt, this sends the same 3-character sequence to your shell. The shell interprets this as a command sequence (typically to recall the previous history item). If you press Ctrl+V then Up at a shell prompt, this inserts the escape sequence at the prompt: Ctrl+V is a command to insert the next character literally instead of interpreting it as a command, so the
␛ character is not interpreted as the start of an escape sequence.
Some keys are only modifiers and are not transmitted to terminal applications. For example, when you press Shift, this information stays in the terminal driver, and is taken into account if you then press A, so the driver sends
A to the application instead of
Additionally some function keys may not be mapped in your console.
For a similar view in the GUI, see What is bash's meta key?