With my experience, I learned C out of a book by doing the examples and exercises. When I fist started programming, I was using GW-BASIC. Then I moved to Pascal and IA32 Assembler. I learned C later on while using FreeBSD. The CIS 001 (Introduction to Computers) class taught at the local College starts people off with programming in Visual Basic (gah!). Then they move to C# and IBM SYS370 assembler in later classes. There are so many languages out there that no one person can learn them all. You have the popular ones like C, C++, Java, VB, VC++, VC#, PHP, Python, and Ruby. Everything basically comes down to using the right tool for the job.
However, UNIX, and subsequently FreeBSD was written in C, which necessitates one to learn C if doing system admin or system programming work. There's a big difference between system programming and application programming. For system programming, anything that can cause a fault in the software must be checked for. A divide by zero error can kill your system (exception in kernel mode causes a system panic). All input must be verified. While working on the other side of the system call tree, you do not have alot of the "nice" functions available to use as you would when working in user space. This has to do with the mission of the kernel being radically different than that of an application.
The expectation of the kernel is resource management. Resources is defined as being hardware devices, files, memory, network, processes, CPU time, and most importantly, security. As a result of this, the kernel library is limited to functions that enable it to achieve that goal. For applications, we all know that their expectations very far and wide. They can be anything from a simple game of pong or chess to the sophisticated control program for a telephone exchange, from something simple like your digital wrist watch to something that people's lives depends on such as space craft navigation, the point defense system on a naval warship, to a flight control computer on an aircraft.
In my time, I've seen code that was supposedly written by professional software engineers that was so atrocious I wouldn't turn it in to my dog.
As for the subject on hand, FreeBSD is an excellent platform to learn system programming on. Once you learn it, you can then claim on your resume that you can do system level programming in a UNIX environment. Do this on your own computer at home though. I doubt that an employer would appreciate you causing a panic in a mission critical system. Furthermore, start with writing kernel modules. You don't want to start modifying kernel source right off the bat because you can end up with a non-bootable system if you screw up (Yes, speaking from experience here.). If you do modify kernel source, make sure you make a backup copy of your existing kernel in case something goes wrong...and something will go wrong...trust me.
Other people have given some very good resources for you to look at so I won't list them here. But, a prerequisite is to learn C, which you are doing. In the kernel, there is some machine specific code that is written in assembler for the target platform, but that's for CPU specific stuff such as memory protection, virtual memory, context switching, locks, and the like.