A string can be of any length, but when accessing .charAt() you're accessing a data structure with an index.
These work on a system that starts with the first element at 0 in Java, as opposed to 1.
For example, if you wanted to access the first letter in the string, it would be start.charAt(0).

If the length of the variable 'start' is equal to n, then the index must be n - 1 (length - 1) to access the same corresponding value/char in the data structure.
If you don't use length - 1, you effectively access a char that doesn't exist. Say that the length of 'start' is 8, then characters will only occupy .charAt(0) to .charAt(7). If you try to access .charAt(8) using just length, there is no data to access as it's beyond the array limit and therefore will fail to execute.
I'll do a quick rundown of the code too as I always feel theory helps with a familiar context. I don't wish to be patronising, I just want to reinforce the knowledge.
start = input.nextLine();
int length = start.length();
for(length = length - 1 ; length >= 0 ; length--)
end = end + start.charAt(length);
In your code example you:
Take in an input (start)
Find the length of the input (length)
Enter a for loop, where 'length' is subtracted by 1 to get the correct index. If 'length' is bigger than or equal to 0, it is decremented by 1 (moving the index down by 1).
The char at the index position in the array is then added to the variable 'end'.
This is then repeated to take the indexed letter from the string 'start' and place them at the front of the new string 'end', therefore reversing the order.
Hope this has helped!